I created a Vue project using Vue CLI 3 using all the default preset options. When I run the app in Chrome using vue serve, I noticed that the elements inside the head element don't match the head elements inside /public/index.html at all. I read that I could add the meta elements I want inside vue.config.js, but when I go to run the app it doesn't seem to use that file. My vue.config.js looks like this:
module.exports = {
chainWebpack: config => {
config
.plugin('html')
.tap(args => {
args[0].title = 'MyApp title';
args[0].meta = {viewport: 'width=device-width,initial-scale=1,user-scalable=no'};
return args;
})
}
}
And the HTMLWebpackPlugin portion of vue inspect looks like this:
/* config.plugin('html') */
new HtmlWebpackPlugin(
{
templateParameters: function () { /* omitted long function */ },
template: '/*path-to-project-root*/node_modules/#vue/cli-service/lib/config/index-default.html'
}
)
...
...which looks like it isn't even pointing to /public/index.html.
I don't really know where to look next, any help would be appreciated.
You can set meta data from within the page components
<script>
head () {
return {
title: 'my title,
meta: [
{ hid: 'description', name: 'description', content: 'my description' }
]
}
</script>
Related
I am building a custom Nuxt3 module and want to use tailwindcss to style
my components.
However, I am having trouble setting up tailwindcss for my module.
I tried to set it up, like I would with a normal css file:
In the 'src/' folder I have the follwing components:
'runtime/css/tailwind.css':
#import "tailwindcss/base";
#import "tailwindcss/components";
#import "tailwindcss/utilities";
'runtime/tailwind.config.js':
import defaultTheme from ("tailwindcss/defaultTheme")
module.exports = {
content: {
files: [
"./components/**/*.{vue,js}",
"./layouts/**/*.vue",
"./pages/**/*.vue",
"./plugins/**/*.{js,ts}",
"./modules/**/*.{js,ts,vue}"
],
},
theme: {
extend: {
fontFamily: {
sans: ['"Inter var"', ...defaultTheme.fontFamily.sans],
},
},
},
variants: {
extend: {},
}
};
'module.ts':
import { resolve } from 'path'
import { fileURLToPath } from 'url'
import { defineNuxtModule, addPlugin, addComponent } from '#nuxt/kit'
export interface ModuleOptions {
css: boolean
}
export default defineNuxtModule<ModuleOptions>({
meta: {
name: '#nuxt-module/polkadotjs-wallet',
configKey: 'polkadotjs-wallet'
},
defaults: {
css: true,
},
setup (options, nuxt) {
const runtimeDir = fileURLToPath(new URL('./runtime', import.meta.url))
nuxt.options.build.transpile.push(runtimeDir)
// add the plugin
addPlugin(resolve(runtimeDir, 'plugin'))
// add components
const componentsDir = resolve(runtimeDir, "components")
addComponent({
name: "Hello",
filePath: resolve(componentsDir, "Hello.vue")
})
if(options.css) {
nuxt.options.css.push(resolve(runtimeDir, "css/tailwind.css"))
}
}
})
While this approach works to use normal css styling, I cannot make tailwind work like that.
Running it like this does not give me an error, but it also does not enable me to use tailwind.
I think I find a way, but I'm just discovering Nuxt 3.
Maybe my answer won't be perfect, but as far as I read the documentation and the #nuxtjs/tailwindcss code, that's all I found to work.
move your runtime/css/tailwind.css to runtime/tailwind.css
I'm not sure this file is really useful, as there is a default one provided by #nuxtjs/tailwindcss (see in your node_modules/#nuxtjs/tailwindcss/dist/runtime/tailwind.css)
update your tailwind.config.js for content property. It's an array of string for me. Actually, your paths are relatives. But in your app, these paths will take the components app and not the one of your module. You need to give absolute paths.
import defaultTheme from ("tailwindcss/defaultTheme")
import { fileURLToPath } from 'node:url'
const srcDir = fileURLToPath(new URL('../', import.meta.url))
/** #type {import('tailwindcss').Config} */
export default {
content: [
srcDir + '/**/*.{js,ts,vue}', // or separate in folders ?
],
theme: {
extend: {
fontFamily: {
sans: ['"Inter var"', ...defaultTheme.fontFamily.sans],
},
},
},
variants: {
extend: {},
}
};
last part, but the most important, you need to update your module.ts. I would write yours like this :
async setup (options, nuxt) {
const runtimeDir = fileURLToPath(new URL('../src/runtime', import.meta.url))
/**
* Here, you use the installModule to specify that
* your module USE the #nuxtjs/tailwindcss module.
* I think this is the way to add the tailwind module
* to your playground, or the app that will use your module
*/
await installModule('#nuxtjs/tailwindcss', {
/**
* Here, you specify where your config is.
* By default, the module have a configPath relative
* to the current path, ie the playground !
* (or the app using your module)
*/
configPath: resolve(runtimeDir, 'tailwind.config'),
})
// add components
const componentsDir = resolve(runtimeDir, "components")
addComponent({
name: "Hello",
filePath: resolve(componentsDir, "Hello.vue")
})
/**
* for these lines, I don't know if they are still useful
* please check them before keeping them :-)
*/
const runtimeDir = fileURLToPath(new URL('./runtime', import.meta.url))
nuxt.options.build.transpile.push(runtimeDir)
// add the plugin
addPlugin(resolve(runtimeDir, 'plugin'))
if(options.css) {
nuxt.options.css.push(resolve(runtimeDir, "css/tailwind.css"))
}
}
Does this help you ?
References :
installModule for Nuxt3 Modules
default configPath for #nuxtjs/tailwindcss
here is code that i try
head: {
script: [
{
src: "https://maps.googleapis.com/maps/api/js?key=MYKEY&libraries=places&callback=initAutocomplete",
},
],
},
mounted() {
new google.maps.places.Autocomplete(
document.getElementById('autocomplete')
)
},
And i got this error
Thanks for any help
When you go to import the googlemaps scripts it is not said that the script has already been loaded.
The best thing is to put a global hook and then emit an event like maybe an eventHub.
Example of event hub https://www.digitalocean.com/community/tutorials/vuejs-global-event-bus
//your mapsPlugin.js
import eventHub from "./your-event-hub";
window.initAutocomplete = () => {
eventHub.$emit("maps-loaded");
};
mounted() {
// mounted of your component
eventHub.$on("maps-loaded", () => {
// your stuff
});
},
You can try:
Introduced in the index.html page
<script src="https://maps.googleapis.com/maps/api/js?key=MYKEY&libraries=places&callback=initAutocomplete"></script>
new google.maps.places.Autocomplete() change into new window.google.maps.places.Autocomplete();
I am trying to find out how to use the same page for multiple routes on a Nuxt.js with i18n module.
Basically I want this route: /product-category/:slug/in/:material to use the same page as /product-category/:slug
So far I have tried below, adding it to nuxt.config.js - but it doesn't work. It simply shows the _slug/_material/index.vue file.
router: {
extendRoutes (routes, resolve) {
routes.push({
path: '/product-category/:slug/in/:material',
component: resolve(__dirname, 'pages/product-category/_slug/index.vue')
})
}
},
Maybe because I am having the i18n module, maybe because I am doing something wrong.
This is my folder structure:
If I inspect my router.js file, I see the path shown twice:
This was my workaround, I just wish there was a simpler method. Plus it still works if you use nuxt i18n.
nuxt.config.js
router: {
extendRoutes (routes, resolve) {
const routesToAdd = [
{ // add your routes here
name: 'product-category-slug-material',
path: '/product-category/:slug/in/:material',
component: resolve(__dirname, 'pages/product-category/_slug/index.vue'), // which component should it resolve to?
chunkName: 'pages/product-category/_slug/_material/index' // this part is important if you want i18n to work
}
];
const existingRoutesToRemove = routesToAdd.map(route => route.name);
const generateRoutes = routes.filter((route) => {
return !existingRoutesToRemove.includes(route.name);
});
routesToAdd.forEach(({ name, path, component, chunkName }) => {
generateRoutes.push({
name,
path,
component,
chunkName
});
});
routes.splice(0, routes.length, ...generateRoutes); // set new array
}
},
You can use _.vue to catch everything.
If you do not know the depth of your URL structure, you can use _.vue to dynamically match nested paths. This will handle requests that do not match a more specific request.
Here you can find out more.
I am new in using vue to build web app.
By default, use npm run build, it will build the following structure:
But I hope to build as follow:
Then, how can I write the vue.config.js as output like what I want?
Using this GitHub issue as an example, you should be able to achieve this by adding something like this to your configuration...
// vue.config.js
module.exports = {
chainWebpack: config => {
config.module.rule('images').use('url-loader')
.loader('file-loader') // replaces the url-loader
.tap(options => Object.assign(options, {
name: 'images/register/[name].[hash:8].[ext]'
}))
config.module.rule('svg').use('file-loader')
.tap(options => Object.assign(options, {
name: 'images/register/[name].[hash:8].[ext]'
}))
},
css: {
extract: {
filename: 'css/register/[name].[hash:8].css',
chunkFilename: 'css/register/[name].[hash:8].css'
}
},
configureWebpack: {
output: {
filename: 'js/register/[name].[hash:8].js',
chunkFilename: 'js/register/[name].[hash:8].js'
}
}
}
See https://cli.vuejs.org/config/#vue-config-js for more information and examples.
This question already has answers here:
Async load routes data and build route instruction for Angular 2
(4 answers)
Closed 6 years ago.
Maybe anyone know how to dynamicly build routes (or just dynamic import Components).
For example:
I have JSON that contains objects with RouteName, path, ComponentNames (string).
I want to iterate it and build dynamicly routes definitions (route config). But I don`t know, how to make dynamic Component import.
I can passs string "ComponentName" from JSON to import rule, because import want static definition (finded it on some soure from googling).
failed
let a = "MyComponentName"
import {a} from ......
(One idea that I came up with - its like create some map key-value, and keep into key - route, value - Component, and after that equals routename from JSON and my MAP and push needed component into final route config array. But its so ugly solution) Maybe another way exists?
I stuck. Many thanks for any help.....
You could leverage Async routes to do this. Based on your route configuration, you could load route from modules. In this case, you need to add the module path to get the components to associate with routes.
Here is a sample:
var routes = {
path: '/path',
name: 'some name',
module: './my.component',
component: 'MyComponentName'
}
routes.forEach((route : any) => {
this.routeConfigArray.push(
new AsyncRoute({
path : route.path,
loader : () => System.import(route.module).then(m => m[route.component]),
name : route.name
});
);
});
this._router.config(this.routeConfigArray);
Another approach could be to add a function to get the name of functions. Based on this you can check if you have a potential component that matches.
Here is a sample:
ngOnInit() {
this.routes = [
{
path: '/test', component: 'OtherComponent', name: 'Test'
}
];
this.configureRoutes(this.routes);
this.router.config( this.routes);
}
configureRoutes(routes) {
var potentialComponents = [ OtherComponent ];
routes.forEach((route) => {
route.component = potentialComponents.find((component) => {
return component.name === route.component;
});
});
}
See this plunkr: https://plnkr.co/edit/KKVagp?p=preview.
See this question for more details:
Dynamic Route Loading in Angular 2 Fails. (Beta)
https://github.com/angular/angular/issues/11437#issuecomment-245995186 provides an RC.6 Plunker
update
In the new router (>= RC.3) https://angular.io/docs/js/latest/api/router/index/Router-class.html#!#resetConfig-anchor resetConfig can be used
router.resetConfig([
{ path: 'team/:id', component: TeamCmp, children: [
{ path: 'simple', component: SimpleCmp },
{ path: 'user/:name', component: UserCmp }
] }
]);
original
What should work is
import from 'myComponents' as myComponents;
...
someFunc(name:string) {
console.debug(myComponents[name]);
}
Routes can be loaded using
constructor(private router:Router) { }
someFunc() {
this.router.config([
{ 'path': '/', 'component': IndexComp },
{ 'path': '/user/:id', 'component': UserComp },
]);
}
I haven't tried this myself.
See also this related question Angular2 App Routing through Services
say. three screens as page1, page2 and page3 and components as app/page1.ts, app/page2.ts and app/page3.ts
let screens : Array<string> = ["Page1","Page2","Page3"];
let aRouter : RouteDefinition;
this.routes = new Array<RouteDefinition>();
screens.map(function(screenId){
aRouter = new AsyncRoute({
path: "/" + screenId,
name: screenId,
loader: () => System.import("app/" + screenId).then(c => c[screenId]) // not import {page1, page2, page3}}
});
this.routes.push(aRouter);
}.bind(this)); //we need to bind to current "this" instead of global this
this.router.config(this.routes);
trick is .bind(this), which is vanella javscript
for whole sulution, check this
Dynamically load Angular 2 Async router
https://github.com/Longfld/DynamicalAsyncRouter