vueuse / head Goto Github PK
View Code? Open in Web Editor NEWDocument head management for Vue. Powered by Unhead. - ๐ Sunset
Home Page: https://unhead.unjs.io/setup/vue/installation
License: MIT License
Document head management for Vue. Powered by Unhead. - ๐ Sunset
Home Page: https://unhead.unjs.io/setup/vue/installation
License: MIT License
Hey so maybe a stupid question, but I am a bit new to Vue.
I am getting an error "You may forget to apply app.use(head)" but my main.js code looks like this;
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import { projectAuth } from './firebase/config';
import { createHead } from '@vueuse/head';
//wait firebase to get user
let app;
const head = createHead()
projectAuth.onAuthStateChanged(() => {
if (!app) {
app = createApp(App).use(router, head).mount("#app");
}
});
my .use has (router) previously, so added (router, head) is this correct? IF so, any ideas what my error may be in regards to?
I am getting the following error when attempting to compile our code
ERROR in ../node_modules/@vueuse/head/dist/index.mjs 349:27-42 Can't import the named export 'defineComponent' from non EcmaScript module (only default export is available)
I followed the readme instructions for npm
install and then the standard import of the code.
import { createHead } from '@vueuse/head'
"@vueuse/head": "^0.6.0"
"webpack": "^4.46.0"
running Node: v14.17.1
Thanks!
Might be nice to create Vue component/s to allow users to interact with the head as managed by @vueuse/head
within the <template>
. Is this on your roadmap/would you welcome adding this to the project?
Hello.
I'm using vue3 and composition api im my project.
I managed to add dynamic meta tags to the html head section:
However, the link share on social netwroks is not fecthing and previewing these contents. Any clue of what is happening?
In facebook share debugger tool i have at least a warning:
Inferred Property
The 'og:image' property should be explicitly provided, even if a value can be inferred from other tags.
But this property is defined. I'm thinking when the facebook scraps my page, these properties aren't yet on the page...
Anyone can help me understand what is going on and how to solve this?
In my index.html I have set up some meta tags as a fallback if my prerenderer fails (for some reason). When I use @vueuse/head
and I set a meta tag I have already set in my HTML file, I end up with duplicate meta tags. Since new meta tags are created at the end of the head tag, duplicate tags technically won't matter but I find it a bad practice. Could you please support the replacement of tags if they already exist?
Hello thanks for this plugin. I wanna use this with vite-plugin-ssr and tried something simple. As I see <title> is not created in server side.
Here are the example:
I cloned https://github.com/brillout/vite-plugin-ssr/tree/master/examples/vue-router and added @vueuse/head
https://github.com/ozergul/vite-ssr-usehead
What can be done?
Some sample HTML generated by renderHeadToString
:
<title>Welcome to my startup</title><link rel="stylesheet" href="https://fonts.xz.style/serve/inter.css"/><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@exampledev/[email protected]/new.min.css"/><script preload="" src="/analytics.js" async="" defer=""/>
In particular, self closing <script />
tag will cause the rest of the document not to be rendered at all in some browsers. All these head elements can just be rendered without the slash.
<script>
tags are re-created which means the browser re-fetches/executes their content
context: nuxt/nuxt#12814
We currently use @vueuse/head
for managing meta tags in Nuxt, but we don't have support for rendering script tags outside of <head>
- required (for example) by https://github.com/nuxt-community/color-mode-module.
It would be nice to add support.
related: nuxt/nuxt#13345
Hello.
I'm using RankMath - a well known WordPress SEO plugin.
The plugin gives me a string that contains all the html that needs to go in the section of the page.
e.g "<title>some title</title>".
As i mentioned the data im getting from the plugin is a string of html elements.
When i try to pass the string to the component like so:
It doesn't work. Anyway to fix this? Or some other way to achieve the desired result?
I saw some extra data-XX
attributes was generated via renderHeadToString
:
<html class='home-page' data-head-attrs='class'>
<head>
<title>home page</title>
<meta name='head:count' content='0'>
</head>
<body class='home-page-body' data-head-attrs='class'>
<div id='app'>
<div>hi
<main>world</main>
</div>
</div>
</body>
</html>
in this example: data-head-attrs
,<meta name='head:count' content='0'>
what's the purpose of this? Can I remove them?
Currently, a script gets its content rendered as attributes. It would be useful to render its "content" prop as children instead in order to support ld+json.
Hi,
It could be really cool to have a titleTemplate like vue-meta, to be able to set a part of title for each page, and a global part.
For now, I've just made my own use head that just do that:
import { useHead as originalUseHead, HeadObject } from '@vueuse/head'
export const useHead = (head: HeadObject) => originalUseHead({
...head,
title: `${head.title} - MyProject`
})
But it can't be customized in the app.
Thanks for your amazing work,
Mathieu.
Would it be possible to change the favicon depending on a variable, using this plugin?
When using the (seemingly now-deprecated) vue-meta, there was a way to tie into existing meta tags when mounting vue.
Specifically, you could add an attribute, e.g. vmid
( see https://vue-meta.nuxtjs.org/faq/#unique-metadata )
<meta name="description" data-vmid="some_unique_value" content="This is blue.">
And then when using vue w/ vue-meta, you could reference this meta like so:
head() {
return {
meta: [{
'vmid': 'some_unique_value',
'name': 'description',
'content': 'This is red.'
}]
};
}
And the meta tag would be replaced, as you would expect.
However, in vueuse/head, I don't see that such an option exists. I see that there is a reference to "key", but this only works if the meta you are replacing was created using vueuse/head in the first place, and not for previously existing meta.
Is there any option to define an order of the head stuff? Or to define specific stuff to be loaded at the end of head?
I have the problem, that i use vueuse/head for my font face definitions in style tag and also for preloading of the fonts.
But the font faces get loaded before the fonts. That results in following warning
Because there is no font face definition AFTER the font loading.
It can be fixed when the style tag with font face definition is at the very end of head. But i don't find a configuration how to achieve this with vueuse/head.
I think there are use cases where the order in the head can be important.
Note: using vueuse/head with SSR
Just as name
and property
are used to deduplicate, we should likely also dedupe <meta charset>
tags.
I am working on a SSR sharing plugin so that the title is generated on server side.
the case is setting head in one component while getting head on another component.
How can I achieve that?
I can get the title with this.
useNuxtApp().vueApp.config.globalProperties.$head.headTags.filter(x => x.tag === 'title').filter(x => x.tag === 'title').reverse()[0].props.children
Any simpler way to get it?
I'm trying to define <meta />
tags using a v-for
<template>
<Head>
<title>{{ metaInfo.title }}</title>
<meta
v-for="tag in metaList"
:key="tag.name"
:name="tag.name"
:content="tag.content"
/>
</Head>
</template>
<script>
{
data() {
return {
metaList: [{
name: "test",
content: "test",
}],
};
},
}
<script>
This produces no meta. If I remove the v-for
and use directly indices, it starts to work.
Any idea of how can achieve this?
Thanks!
renderHeadToString({
headTags: [
{
tag: 'script',
props: {
async: true,
hid: 'maps-googleapis',
src: 'https://maps.googleapis.com/maps/api/js?key=example&libraries=places',
},
},
],
}).headTags
results in:
<script async hid="maps-googleapis" src="https://maps.googleapis.com/maps/api/js?key=example&libraries=places"></script><meta name="head:count" content="1">
https://github.com/vueuse/head/blob/main/src/stringify-attrs.ts#L2-L32
https://github.com/vueuse/head/blob/main/src/index.ts#L347-L362
Here's a reproduction.
When using useHead
on parent and children component with vue-router, everything works fine but during transition, vueuse/head
re-trigger parent head and cause FOUC.
Reproduction :
https://codesandbox.io/s/nameless-grass-b904r
Note : when opening Chrome dev tool, you can also see in Network Tab google font is loaded when navigate from / to /about. If the FOUC is not visible, because the network is too fast, you can throttle network
Apart from that, vueuse/head is incredible, I use for SSR project and I appreciate all the work of this project !
Cheers
JM
I'm using a repo based on vitesse-ssr-template and @vueuse/head
is getting the following when attempting to define the Head
component:
Uncaught ReferenceError: defineComponent is not defined
I've tested this with both vite
and vite-ssr
, and the above happens in both on the client, but running with vite-ssr
will product valid HTML on the server (i.e. the vite
on does not render; the vite-ssr
one renders, but is non-interactive)
Updating vitesse-ssr-template's dependencies should be sufficient to reproduce, but here's my package.json
:
{
// ...
"engines": {
"node": ">=14"
},
"scripts": {
"bi": "bi --pm pnpm",
"fetch": "node ./scripts/fetch-metadata",
"gen": "node ./scripts/generate-entities",
"dev": "vite-ssr --port 3333 --open",
"dev:spa": "vite --port 3333 --open",
"clean": "rm -rf dist; rm -rf api/renderer",
"build": "pnpm clean; cross-env NODE_ENV=production vite-ssr build; ./scripts/move-dist.sh",
"preview": "vc dev"
},
"dependencies": {
"@apollo/client": "^3.3.16",
"@replygirl/tc": "^3.0.0",
"@vue/reactivity": "^3.0.11",
"@vue/server-renderer": "^3.0.11",
"@vueuse/core": "^4.9.1",
"@vueuse/head": "^0.5.1",
"axios": "^0.21.1",
"breeze-client": "^2.1.1",
"element-plus": "^1.0.2-beta.41",
"hash-sum": "^2.0.0",
"node-fetch": "^2.6.1",
"nprogress": "^0.2.0",
"pluralize": "^8.0.0",
"prism-theme-vars": "^0.2.2",
"querystring": "^0.2.1",
"vite-ssr": "^0.8.0",
"vue": "^3.0.11",
"vue-i18n": "^9.1.6",
"vue-router": "^4.0.6",
"vue3-google-map": "^0.7.6"
},
"devDependencies": {
"@antfu/eslint-config": "^0.6.4",
"@iconify/json": "^1.1.337",
"@intlify/vite-plugin-vue-i18n": "^2.1.2",
"@replygirl/curse": "^3.0.0-beta.0",
"@rollup/plugin-graphql": "^1.0.0",
"@types/axios": "^0.14.0",
"@types/btoa": "^1.2.3",
"@types/dotenv-flow": "^3.1.0",
"@types/eslint": "^7.2.10",
"@types/eslint-config-prettier": "^6.11.0",
"@types/eslint-plugin-prettier": "^3.1.0",
"@types/hash-sum": "^1.0.0",
"@types/node": "^14.14.43",
"@types/node-fetch": "^2.5.10",
"@types/nprogress": "^0.2.0",
"@types/pluralize": "^0.0.29",
"@types/prettier": "^2.2.3",
"@types/pug": "^2.0.4",
"@types/rimraf": "^3.0.0",
"@typescript-eslint/eslint-plugin": "^4.22.0",
"@vercel/node": "^1.10.0",
"@vitejs/plugin-vue": "^1.2.2",
"@vue/compiler-sfc": "^3.0.11",
"better-install": "^0.1.0",
"breeze-entity-generator": "^1.0.0",
"btoa": "^1.2.1",
"cross-env": "^7.0.3",
"dotenv-flow": "^3.2.0",
"eslint": "^7.25.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.0",
"markdown-it-prism": "^2.1.6",
"pnpm": "^5.18.9",
"prettier": "2.2.1",
"pug": "^3.0.2",
"rimraf": "^3.0.2",
"ts-node": "^9.1.1",
"type-fest": "^1.0.2",
"typescript": "^4.2.4",
"vite": "^2.2.3",
"vite-plugin-components": "^0.8.4",
"vite-plugin-icons": "^0.5.0",
"vite-plugin-md": "^0.6.3",
"vite-plugin-pages": "^0.10.0",
"vite-plugin-pwa": "^0.7.3",
"vite-plugin-vue-layouts": "^0.2.2",
"vite-plugin-windicss": "^0.14.6",
"vite-ssg": "^0.9.3"
},
// ...
}
I'm using @vueuse/head
v0.6.0 with vite-ssg
and was confused with the following error message that killed the build script because it refers to Node (which I thought meant the language but actually refers to a variable called Node in this case).
ReferenceError: Node is not defined
at /[..]/node_modules/@vueuse/head/dist/index.js:202:55
at Array.forEach (<anonymous>)
The following code in the built script in dist is the culprit:
oldElements.forEach((el) => {
if (el.nextSibling && el.nextSibling.nodeType === Node.TEXT_NODE) {
el.nextSibling.remove();
}
el.remove();
});
There is no Node.TEXT_NODE
imported or defined anywhere so if run this code will fail (although it seems to work fine in the browser at least w/ Vite dev server). This was introduced in #28. My workaround is to use npm version 0.5.1 which works fine, the current 0.6.0 doesn't.
Can this be used in an Options API component? Is there any other way to call it than using the setup function?
Thanks.
According to https://ogp.me/ "If a tag can have multiple values, just put multiple versions of the same tag on your page."
In my use case I want to add multiple tags for the video pages of my website and I am adding these values to the meta
array. The issue is that only 1 of the properties is added due to the fact that the property names are the same.
I have tested this by adding a suffix to each property name and all of the elements are added, although they are no longer valid OG tags.
<meta property="og:video:tag1" content="Bene Gesserit">
<meta property="og:video:tag2" content="Blade Runner 2049">
<meta property="og:video:tag3" content="Coming Soon">
Currently I only get
<meta property="og:video:tag" content="Coming Soon">
The desired outcoume would look like below :
<meta property="og:video:tag" content="Bene Gesserit">
<meta property="og:video:tag" content="Blade Runner 2049">
<meta property="og:video:tag" content="Coming Soon">
I would suggest that a check on the content
property value is performed during the deduplication process in order to allow for the desired output as above.
how can i set my title after data fetched by created() in vue3. my structure is:
data () {
return {
article: null,
}
},
setup() {
const siteData = reactive({
title: this.article.title
})
useHead({
title: computed(() => _title??_)
})
},
async created () {
query({})
.then () = {
this.article = data.articleByID
}
}
At the moment we can't merge classes, for example:
useHead({
htmlAttrs: { class: 'first-class' }
})
useHead({
htmlAttrs: { class: 'second-class' }
})
In this case there will be only one class applied to <html>
rather than merging the two, which is what I would expect...
I have problem with SSR and dynamic meta data loading. For example I have awaiting function getTitle()
and need to set page title after request complete. In console log title value in reactive state is correct, but page title is not - there is still old the value.
Here is my code:
async setup() {
const siteData = reactive({
title: `My website`,
description: `My beautiful website`,
});
useHead({
title: computed(() => siteData.title),
meta: [
{
name: `description`,
content: computed(() => siteData.description),
},
],
})
//Fetch request simulator...
siteData.title = await getTitle();
console.log(siteData.title); //Here is correct value
}
How can I set dynamic meta data? Thank you for your time.
Most of the time, we set page title after async fetch, so we must use computed:
title: computed(() => siteData.title)
why not provide a function to set the reactive object? like this:
import { useHead } from '@vueuse/head'
export default defineComponent({
async setup() {
const setHead = useHead()
setHead({
title: 'static string',
meta: [
{
name: 'description',
content: 'static string',
},
],
})
},
})
And most of the time, we must set title, description and keywords for SEO, so I think we can make it more convenient:
setHead({
title: 'static string',
description: 'static string',
keywords: 'static keywords',
meta: [
// ...
],
script: [
// ...
]
})
The new library looks great. Sorely needed.
From looking at the docs, there is nothing mentioned about providing the context (e.g. the route url
) for the rendering.
I know that renderToString
supports a second context argument:
const HTML = renderToString(app, {url: '/whatever'})
How does the SSR code address this?
What am I doing wrong here? Why am I not seeing the <meta name="description" content="My beautiful website" />
in my source code?
Here's how I am setting up the code:
<template>
<nav class="p-5 bg-green-400 text-white mb-10">
<router-link :to="{ name: 'Home' }">Snazzy Fake Blog</router-link>
</nav>
<div class="container">
<router-view></router-view>
</div>
</template>
<script setup>
import { defineComponent, reactive, computed } from 'vue'
import { useHead } from '@vueuse/head'
const siteData = reactive({
title: `My website`,
description: `My beautiful website`
})
useHead({
// Can be static or computed
title: computed(() => siteData.title),
meta: [
{
name: `description`,
content: computed(() => siteData.description)
}
]
})
</script>
I'd like a way to add a suffix to all titles automatically.
In my use-case, every title from my site should be suffixed with the website name:
Home | privatenumber
Blog | privatenumber
Contact | privatenumber
I'm wondering if it would make sense to add an API to createHead()
:
const head = createHead({
title: (titleValue) => titleValue + ' | privatenumber'
})
app.use(head)
Is it possible to reactive change meta tag content when changing language?
P.S: Not working with reactive func
This line removes all link tags that aren't controlled by vueuse/head:
Line 208 in 392e8c8
If I remove that then this section does the same thing when run by vite-ssg because querySelector('link[key="null"]')
just returns the first <link>
due to a jsdom bug:
Lines 213 to 218 in 392e8c8
Originally posted by @KaelWD in #45 (comment)
Hi,
Probably not an issue but testing this out and can not figure out how add dynamic values in meta.
Base example:
import { defineComponent, computed, reactive } from 'vue'
import { useHead } from '@vueuse/head'
export default defineComponent({
setup() {
const siteData = reactive({
title: `My website`,
description: `My beautiful website`,
})
useHead({
// Can be static or computed
title: computed(() => siteData.title),
meta: [
{
name: `description`,
content: computed(() => siteData.description),
},
],
})
},
})
How can you add a variable in title, like:
import { defineComponent, computed, reactive } from 'vue'
import { useHead } from '@vueuse/head'
export default defineComponent({
setup() {
const siteData = reactive({
title: this.title, // Here
description: `My beautiful website`,
})
useHead({
// Can be static or computed
title: computed(() => siteData.title),
meta: [
{
name: `description`,
content: computed(() => siteData.description),
},
],
})
},
})
I am finding it impossible to add a <script>
tag to the head that contains actual script text rather than just a src
attribute.
I need to add something like the following:
script: [
{
type: "application/ld+json",
text:
{
"@context": "https://schema.org",
"@type": "Product",
"description": "I am product A",
}
}
]
How can I add a <script>
tag with text content so it will render like such:
<script type="application/ld+json"> {
"@context": "https://schema.org",
"@type": "Product",
"description": "I am product A",
}
</script>
Perhaps use id
?
context: #44 and nuxt/nuxt#12980
I found something special in using dynamic reference title in template component. Look at this:
<template>
<div>
<Head>
<title> {{ somethingComputedObject.prop }} </title>
</Head>
.....
</div>
</template>
....
The server monitor show memory leaks in apache benchmark test. Works fine without Head component, or with static text (not reference property). Composition API hook looks well too - I've analyzed problem only in component.
Can you check it please? Thank you.
Hi, I'm using vue-class-component and I have this:
@options({
components: {
HomeComponent,
},
setup() {
useHead(() => ({
title: Spencer: Home
,
meta: [
{
name: description
,
content: hey
,
},
],
}))
}
})
export default class Home extends Vue {}
But, the title isn't changing. Any ideas? Embeds don't work either
Currently useHead()
implements a whitelist of tags that can be added into the <head>
element. I need to add an ESI tag or an HTML comment to load assets originating from another service. These needs to be added conditionally, so even if Nuxt 3 would allow overriding its app.html a solution within useHead()
would be best.
To illustrate, I am currently using this hack:
<template>
<Style v-if="isServer" :children="myCustomTag" />
<NuxtPage/>
</template>
<script setup>
const isServer = process.server
const myCustomTag = ' </style> <!--esi <esi:include src="/foo/bar" />--> <style> '
</script>
This inserts the comment at the cost of two empty <style>
tags. Obviously this can only be a temporary workaround.
I am unsure what the best API would be, maybe just teleport all child elements of <Head>
into <head
>. E.g:
<Head>
<!--esi <esi:include src="/foo/bar" />-->
</Head>
const title = ref('Example title')
useHead(() => ({ title }) )
similar to #32, we can deduplicate canonical links....
Original issue is nuxt/nuxt#14271
Linux
v16.14.0
3.0.0-rc.4
[email protected]
vite
modules
, css
@nuxtjs/[email protected]
-
Use useHead
to assign some CSS classes to body, and then visit the page:
<script setup lang="ts">
useHead({
bodyAttrs: {
class: 'accent-yellow dark-zinc dark'
}
});
</script>
SSR correctly generates classes on body, then on hydration they are removed and then added again, resulting in a very noticeable flicker, especially when these classes are used to switch between dark and light styles of whole page.
For some reason, the link
head object is duplicating in SSR. In Vue 3 I create my head
tags like this:
HTMLHead.value = {
title: `${Product.value[0].title`,
meta: [
{
name: "description",
content: `${Product.value[0].description},
},
{
name: "date",
content: `${Product.value[0].datecreated}`
}
],
link: [
{
rel: "canonical",
href: `https://www.example.com/product/${Production.value[0].urlslug}`
}
]
}
The title
and meta
tags render fine in SSR, but the link
object duplicates each time a page is refreshed. If I navigate to other pages, then those other pages link
elements also appear in the current product page which makes no sense. I cannot understand why it is being duplicated and the title
and meta
objects do not.
Example output I end up with after 3 refreshes of the same page is:
<title>Nintendo Switch</title>
<link rel="canonical" href="https://www.example.com/product/nintendo-switch">
<link rel="canonical" href="https://www.example.com/product/nintendo-switch">
<link rel="canonical" href="https://www.example.com/product/nintendo-switch">
<meta name="description"content="The new Nintendo Switch is availabe now">
<meta name="date" content="2021-09-13T11:55:56.195Z">
The link
tag always ends up being placed immediately after the title
tag and it repeats over and over again (once per page refresh). If I then visit a different product page I end up with this output:
<title>Nintendo Switch</title>
<link rel="canonical" href="https://www.example.com/product/nintendo-switch">
<link rel="canonical" href="https://www.example.com/product/nintendo-switch">
<link rel="canonical" href="https://www.example.com/product/nintendo-switch">
<link rel="canonical" href="https://www.example.com/product/sony-ps4-playstation-4-pro">
<meta name="description" content="The best version of the Sony PS4 is the Pro edition">
<meta name="date" content="2021-09-11T09:21:44.160Z">
So as you can see the old page link
tags still exist and then the new product page link
tag is appended to the end. If a user visits many product pages, they end up with all those link
tags in the final page. This is causing a lot of problems for SEO.
Hello, first at all thank you for the Document manager. Just more like a suggestion, and a question as well, also for people that never had to work with metas in the past like me, might be not aware where and how to configure the ssr part. It's not specify, I also checked the repository looking for this part. In general will be cool to have a tutorial for this plugin because I noticed there not much information around on the web, and the places that I found where just a copy and paste from the read me file. :)
vuejs/core#5416 added two new arguments to the DefineComponent
type, causing the emitted type from earlier versions to throw
node_modules/@vueuse/head/dist/index.d.ts:45:149 - error TS2344: Type 'VNodeProps & AllowedComponentProps & ComponentCustomProps' does not satisfy the constraint 'ComponentProvideOptions'.
Type 'VNodeProps & AllowedComponentProps & ComponentCustomProps' is not assignable to type 'ObjectProvideOptions'.
Index signature for type 'string' is missing in type 'VNodeProps & AllowedComponentProps & ComponentCustomProps'.
45 declare const Head: vue.DefineComponent<{}, () => null, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, vue.EmitsOptions, string, vue.VNodeProps & vue.AllowedComponentProps & vue.ComponentCustomProps, Readonly<vue.ExtractPropTypes<{}>>, {}>;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
i use vue@^3.2.13 and @vueuse/head@^0.6.0, there is reference error while typing computed.
it's not show but i forgot what version of vue that i used before, but after i upgrade this error show up.
Type 'ComputedRef<string | undefined>' is not assignable to type 'MaybeRef<string> | undefined'.
Type 'ComputedRef<string | undefined>' is not assignable to type 'Ref<string>'.ts(2322)
<script setup lang="ts">
import { computed } from "vue";
import { useHead } from "@vueuse/head";
const data = reactive<IMangaResult>({});
useHead({
title: computed(() => data.title),
});
</script>
Hello. I know this maybe not connected with this plugin. But I can't make it work with router.
I have 30+ routes
I would like to get route.name and pass to "title". I tried diff options but none doesn't work.
After this in some components I will change to specific attr
<template>
<animated-router-view />
</template>
<script lang="ts" setup>
import AnimatedRouterView from '@/components/AnimatedRouterView.vue'
import { useRoute } from "vue-router";
import { useHead } from "@vueuse/head";
import { computed, watch } from "vue";
const route = useRoute()
// this option works
// useHead({
// title: 'asd',
// })
// option via watch doesn't work
// with deep true, computed, it doesn't work
watch(route,
(to) => {
console.log(to.name) // work
// doesn't work
useHead({
title: 'asd',
})
}
)
</script>
Hi everybody.
I recently worked on new features that bring script loading strategy to the Nuxt. The problem is when I add some events to the script
component (provided by nuxt as sugar syntax of useMeta), it turned into attributes and prints the event function string on the element.
<script src="./mock.js?t=49" strategy="immediate" onload="function() { console.log('loaded')"></script>
I'm using this module to temporarily add some extra global style - in this case disabling scrolling on the html body, which can be useful in some cases like when a modal or nav is being displayed on top of the main content.
For example, my header/nav component has something like this (written in script setup style):
const isMobileNavOpen = ref(false);
function toggleMobileNav() { isMobileNavOpen.value = !isMobileNavOpen.value; }
// add extra body style to lock scrolling on main content while mobile nav is open
useHead({
style: [{
children: computed(() => (isMobileNavOpen.value ? 'body { overflow: hidden; }' : '')),
}],
});
This works and the style is added/removed as the nav is toggled, locking body scroll as it should.
The problem is that if the component is unloaded, it is not cleaning up after itself and removing the extra style tag.
This happens for example if I navigate to a different route that uses a different layout that does not contain this nav component.
I'm able to fix it by adding a onBeforeUnmount handler like so:
onBeforeUnmount(() => {
useHead({ style: [{ children: '' }] });
});
but to me this was unexpected. I would have thought that any component that uses useHead would clean up after itself before unloading.
Please advise if this is expected or a bug that needs addressing. If it is a bug I can try to dig in and get it fixed.
Thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.