VueJS/Tailwind CSS/VITE: use env variables as colors for a Tailwind theme - vue.js

I have a VueJS setup with Vite, Tailwind CSS and postcss, and would like to define different colors using variables in a .env.name file so that I can apply different color themes depending where the code is deployed.
I tried with a .env file containing
VITE_COLOR="FF0000"
and an import within the tailwind.config.js
...
theme: {
colors: {
primary: import.meta.env.COLOR
}
}
...
However, I get the following error:
SyntaxError: Cannot use 'import.meta' outside a module
What do I have to change to get this to work or is there an even better method?

Tailwind config is CommonJS file (not module) so you cannot use ES6 features like import
You can install package called dotenv
npm i dotenv
Require it on top of your tailwind config file like
require('dotenv').config()
module.exports = {/** */}
create color variable in .env. Note as we require it out of Vite's scope it may not be prefixed with VITE_
ANY_COLOR='#ffc8dd'
Now you can access it in tailwind config
theme: {
colors: {
primary: process.env.ANY_COLOR
}
}
This will work BUT if you change color in .env file you need to rebuild your styles again. If it is OK for you (one deployment - one color anyway) - fine. I personally would suggest another solution based on CSS variables - link to CanIUse
Define variable in CSS file or create style tag within <head> tag in index.html
:root {
--theme-color: #ffc8dd;
}
and in config
theme: {
colors: {
primary: 'var(--theme-color)'
}
}
And that's it - no extra packages, extra work and if you change CSS variable, changes will be applied on the fly - even in production as we are using CSS functionality

Related

How to efficiently add global css using nuxt3 and vite?

I have global sass being included in my project and i cant find an efficient way to add it to the project.
there seems to be 2 popular ways to add css in your project.
vite: {
plugins: [svgLoader()],
css: {
preprocessorOptions: {
scss: {
additionalData: `
#import "~/assets/styles/main.scss";
`,
},
},
},
using vite seems to work but it also seems to inject itself into every component i use, so when i generate my project, i can see my css is repeated multiple times, some files as much as 300 times. the issue is found here on vites side https://github.com/vitejs/vite/issues/4448
css: ["#/assets/styles/main.scss"],
the above option seems to not do it for every component, but normal scoped sass in .vue files doesnt pick up sass variables and mixins on compilation using this method
using additionalData adds it to every page. this item is only meant for mixns and vars, which dont translate into permanent css when built.
basically use only vars in mixins in additionalData then use your global.scss in in css

How to bundle tailwind css inside a Vue Component Package

In one of my projects, I build a nice vue3 component that could be useful to several other projects. So I decided to publish it as an NPM package and share it with everyone.
I wrote the isolate component, build it and publish BUT I use Tailwind css to make the style.
When I publish and install the component everything is working BUT without the beauty of the css part.
I tried several configurations and alternative tools to generate the package that automatically add the tailwind as an inner dependency to my package.
Does someone have experience with this? how can build/bundle my component by adding the tailwind CSS instructions into it?
You're almost there
Since you've got your component working, the majority of the part has been done.
For configuring the styling of the component you need to identify the Tailwind CSS classes being used by your Vue component package and retain them in the final CSS that is generated by the Tailwind engine in your project.
Follow below steps in the project where you want to use your tailwind vue component package.
For Tailwind CSS V3
// tailwind.config.js
module.exports = [
//...
content: [
"./index.html",
"./src/**/*.{vue,js,ts,jsx,tsx}",
"./node_modules/package-name/**/*.{vue,js,ts,jsx,tsx}" // Add this line
// Replace "package-name" with the name of the dependency package
],
//...
]
For Tailwind CSS V2
// tailwind.config.js
module.exports = [
//...
purge: {
//...
content: [
"./index.html",
"./src/**/*.{vue,js,ts,jsx,tsx}",
"./node_modules/package-name/**/*.{vue,js,ts,jsx,tsx}" // Add this line
// Replace "package-name" with the name of the dependency package
],
//...
//...
}
]
The content property in the tailwind.config.js file defines file path pattern that the tailwind engine should look into, for generating the final CSS file.
For Pro users
You may also try to automate the above setup by writing an install script for your npm package to add this configuration to the tailwind.config.js file
References
Tailwind Docs - 3rd party integration
It's a bit difficult for someone to answer your question as you've not really shared the source code, but thankfully (and a bit incorrectly), you've published the src directory to npm.
The core issue here is that when you're building a component library, you are running npm run build:npm which translates to vue-cli-service build --target lib --name getjvNumPad src/index.js.
The index.js reads as follows:
import component from './components/numeric-pad.vue'
// Declare install function executed by Vue.use()
export function install (Vue) {
if (install.installed) return
install.installed = true
Vue.component('getjv-num-pad', component)
}
// Create module definition for Vue.use()
const plugin = {
install
}
// Auto-install when vue is found (eg. in browser via <script> tag)
let GlobalVue = null
if (typeof window !== 'undefined') {
GlobalVue = window.Vue
} else if (typeof global !== 'undefined') {
GlobalVue = global.Vue
}
if (GlobalVue) {
GlobalVue.use(plugin)
}
// To allow use as module (npm/webpack/etc.) export component
export default component
There is no mention of importing any CSS, hence no CSS included in the built version.
The simplest solution would be to include the index.css import in your index.js or the src/components/numeric-pad.vue file under the <style> section.
Lastly, I'm a bit rusty on how components are built, but you might find that Vue outputs the CSS as a separate file. In that case, you would also need to update your package.json to include an exports field.

Markdown styles not getting loaded in Nuxt + Vue project

I am working on a Vue + Nuxt + Tailwind project and using the marked library to convert a text into markdown.
The issue is that some styles like "Headings" and "Link" are loading properly, while some basic styles like "bold", "italics" are working fine.
For example:
When I use "*hello* world", it gets converted to "hello world".
When I use "# hello world", it does not increase the size of the text.
When I use "[google](https://google.com)", it does create a link, but the link is not blue colored.
Not sure what the issue is here. If any more details are required, please let me know.
Its because of the tailwind.css
in tailwind, h1 - h6 headers dont work.
Option 1)
add this to your tailwind.config.js:
module.exports = {
corePlugins: {
preflight: false,
},
....
}
source :https://github.com/tailwindlabs/tailwindcss/issues/1460
Option 2)Try adding custom css for h1..h6 in your css file.
https://www.w3schools.com/tags/tag_hn.asp copy the styles from here
Similarly try add custom css for other issues.
The solution to this was using Tailwind CSS's typography plugin.
Here are the steps to be followed:
Install the plugin first.
Using npm
npm install #tailwindcss/typography
Using Yarn
yarn add #tailwindcss/typography.
Then add the plugin to your tailwind.config.js file:
// tailwind.config.js
module.exports = {
theme: {
// ...
},
plugins: [
require('#tailwindcss/typography'),
// ...
],
}
Then add the prose class to the element where you are displaying the markdown.
<div class="prose" v-html="cleanedMarkdown"></div>.
This provided the needed formatting for the markdown.

Importing SCSS variables in Vue components

I recently switched from Vue-CLI to laravel-mix, the usage of SCSS variables worked perfectly with Vue-CLI and now doesnt seem to work anymore at all after I switched to laravel-mix.
Vue-CLI just handled everything for me and I feel like I have to configure something to get the variables to work in laravel-mix.
This is what I've tried (and what worked with Vue-CLI):
// vue component
import variables from "#/styles/variables.scss";
// ...
data() {
return {
variables
}
}
methods: {
test() {
console.log(this.variables)
}
}
// scss
$variable: #FFFFFF;
:export {
variable: $variable;
}
Edit: To clarify, this log outputs an empty object, not undefined.
For this thing to work you need to follow that particular steps
Make Your Variables File. As you made your scss file inside your style its not good you need to make inside /assets/sass/
Add Variables File To App.scss. For that thing you need to import newly create file inside your app.scss by #import 'folder/file';
Add Alias To webpack.mix.js. What we essentially need to do is define an alias or variable that contains the path to our sass directory so we can include that SASS in our Vue components. Just add alias like this in your webpack
resolve: {
alias: {
'#': path.resolve('resources/assets/sass')
}
}
Last thing add Navigation Vue Component. You can import scss variables by adding #import '~#/folder/fie.scss'; in the vue component

Overriding Vuetify variables

I'm using Vuetify in my project, and I want to use a variable file to override the styles generated by Vuetify.
I'm loading the components and their corresponding styles using the a-la-carte method, so I'm NOT importing the Vuetify SASS file using this:
#import '~vuetify/src/styles/styles.sass'
// Not using this method because I don't want to generate styles that are not being used by
// vuetify components I'm not using
Also, my project is using *.scss, not *.sass.
I'm also injecting a global SCSS file containing mixins and other variables in my vue.config.js:
css: {
sourceMap: productionSourceMap,
loaderOptions: {
scss: {
prependData: `#import '#/scss/_common.scss';`
}
}
},
I included a Vuetify variable, $border-radius-root, in that common.scss file, but it doesn't seem to have any effect.
Any idea how to do what I want without having to write entirely new CSS rules to override Vuetify's generated stylesheet? Basically I want to change the units that Vuetify uses using their own stylesheet generator.
Actually the solution is, and I'm dumb for not thinking of this before, to add another loader to vue.config.js:
css: {
sourceMap: productionSourceMap,
loaderOptions: {
scss: {
prependData: `#import '#/scss/_common.scss';`
},
sass: {
prependData: `#import '#/sass/_vuetify-variables.sass';`
}
}
},
Since vuetify is using sass as the css pre-processor, it needs sass-loader to handle the variable overrides and apply it to the framework.
If you are using Nuxt:
you can add customVariable path in your nuxt.config.js file, in vuetify object
Note you have to enable treeShake. This option is required for custom SASS variables to work
example:
vuetify: {
// usually file should be in assets folder
customVariables: ['~/path/to/variables.scss'],
treeShake: true,
}
If you are using Vue CLI:
Create a folder with name: sass, scss, or styles
Create new file inside this folder and name it: variables.scss or variables.sass
vuetify-loader will automatically bootstrap your variables into Vue CLI’s compilation process, overwriting the framework defaults.
From Vuetify docs:
If you have not installed Vuetify, check out the quick-start guide. Once installed, create a folder called sass, scss or styles in your src directory with a file named variables.scss or variables.sass. The vuetify-loader will automatically bootstrap your variables into Vue CLI's compilation process, overwriting the framework defaults.
So, the vuetify-loader automatically loads #/scss/variables.scss in a Vue CLI project, so you could set $border-radius-root in that file, and it will overrride the framework default.