ktquez / vue-head Goto Github PK
View Code? Open in Web Editor NEWManager the meta information of the head tag, a simple and easy way
License: MIT License
Manager the meta information of the head tag, a simple and easy way
License: MIT License
I want to update the title and meta-tags after the page-content is loaded via REST-API, so the final values don't exist when the component is created.
Unfortunately, the meta-tags and title won't react to changes in the data-variables:
<template lang="pug">
.sections
</template>
<script>
import { fetchData } from '../../../js/mixins'
export default {
name: 'HomeTemplate',
data () {
return {
[...],
getcontent: {
contents: {
myTitle: ''
}
}
meta: {
myTitle: ''
}
}
},
[...],
head: {
title: function () {
return {
inner: this.meta.myTitle
}
},
meta: function () {
return [
{ name: 'description', content: this.meta.myTitle, id: 'desc' }
]
}
},
methods: {
[...],
setMetaData () {
if (typeof this.getcontent !== 'undefined') {
if (this.getcontent.contents.headline !== '') {
this.meta.myTitle = this.getcontent.contents.headline
}
}
},
fetchMyData () {
const _this = this
let contentPath = ''
let teaserPath = ''
// Set API-Paths
if (process.env.NODE_ENV === 'development') {
contentPath = '../../static/testData/contents/home.json'
teaserPath = '../../static/testData/contents/home_teaser.json'
} else {
contentPath = '/?_format=json'
teaserPath = '/rest_extended/front_content?_format=json'
}
// Fetch Data
fetchData(_this, contentPath, 'getcontent', function () {
fetchData(_this, teaserPath, 'teasers', function () {
_this.setMetaData()
})
})
}
}
}
</script>
this.meta.myTitle
changes correctly in the vue-console, but nothing happens in the <title>
or <meta name="description">
VueJS: 2.0.0-beta.8
VueHead: 2.0.0
main.js
import Vue from 'vue'
import VueHead from 'vue-head'
import App from './App'
// VueHead for managing Metadata
// https://github.com/ktquez/vue-head
Vue.use(VueHead)
/* eslint-disable no-new */
new Vue({
render: h => h(App)
}).$mount('app')
App.vue
<template lang="pug">
//- Overall
.overall
</template>
<script>
export default {
name: 'App',
head: {
title: {
inner: 'It will be a pleasure'
}
}
}
</script>
<style lang="sass">
</style>
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>1000grad.de</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<app></app>
<!-- built files will be auto injected -->
</body>
</html>
https://jsfiddle.net/6v5z1ks5/
The title remains 1000grad.de
, also other meta-tags I edit...
Greetings,
Wondering if you'd like to implement a simple whitespace trim before the title's final output? Currently it leaves whitespaces if for example my separator and complement are single whitespace strings (can't set actual zero-length strings).
var title = obj.inner + ' ' + (obj.separator || opt.separator) + ' ' + (obj.complement || opt.complement);
window.document.title = title.trim();
ReferenceError: window is not defined
at F:\zhs\node_modules.2.0.10@vue-head\vue-head.js:7:17
Hello, thanks for sure a library, it's really helping me but i will like to know how to change the content in the meta function Asynchronously
for example
self.meta: function () { return [ { name: 'description', content: this.meta.description, id: 'desc' }, { name: 'application-name', content: this.meta.application_name }, // Twitter { name: 'twitter:title', content: this.title }, // with shorthand { n: 'twitter:description', c: this.meta.description }, // Google+ / Schema.org { itemprop: 'name', content: this.meta.application_name }, { itemprop: 'description', content: this.meta.description }, // Facebook / Open Graph { property: 'fb:app_id', content: '15024009' }, { property: 'og:title', content: this.title }, // with shorthand { p: 'og:image', c: 'http://example.com/static/favicon.png' } ] }
If I use param with route in head, it works, but it won't change if I change to another param .
head: {
title() {
return {
inner: `${this.$route.params.type}file`
}
}
}
In vue 2.0 events
is deprecated and this
is undefined on destroy
hook
Maybe a fix
beforeCreate() {
this.$on('updateHead', () => {
init.bind(this)(true)
util.update()
})
},
mounted () {
init.bind(this)()
},
watch: {
'$route' {
this.$emit('updateHead')
}
},
beforeDestroy () {
this.$off('updateHead')
destroy(this.$options.head)
},
Great idea for a library, however by following your recomendation to read https://github.com/joshbuchea/HEAD it's not really obvious as to how I should be structuring the object inside head
.
For instance, your example of setting the document title:
...
head: {
title: {
separator: ' - ',
inner: 'Foo',
complement: 'Bar'
}
},
...
I am unable to find the words inner
or compliment
on https://github.com/joshbuchea/HEAD.
Why when emit updateHead with the title inner not replace but append with the default value
Open Graph recognizes:
<meta property="og:url" content="https://www.mysite.com">
But not:
head: {
meta: [
{ property: 'og:url', content: 'https:/www.mysite.com' }
],
It seems that OG only checks the index.html and does not wait for any js? In that case vue-head is useless and the README.md wrongly specifies it can be used?
Using opengraphcheck.com
to test.
In accordance to last issue about remove of meta,title,links etc before route changes, it would be helpfull the existence of an api to handle better the tool
Hello,
Is it so that only settings that are can be set globally are 'complement' and 'separator'?
I wish to add links as well for components globally, instead of defining them in every component.
I use single file components.
I've tried to put 'link' option to Vue.use(VueHead, {options}} options object without luck.
With Vue 2.0 async update stopped working. No errors are begin displayed.
I've checked your example but i think it can't run since uses "ready" method that got deprecated in Vue 2.0 :s
https://github.com/ktquez/vue-head/blob/master/example/index.html#L98
Edit: I had 2.0.6.. soz.
TypeError: this is undefined
if (!this.$options.head) return
/**
* Remove the meta tags elements in the head
*/
function destroy () {
if (!this.$options.head) return
util.undoTitle(diffTitle)
util.undo()
}
First of all, the library is great! Very simple to use. Now the question:
For example, I would like to have a Component that will have a custom fb:app_id
. But to get this id, I will have to make a request to the server.
But my tests failed, even using the functions to return the components. I tried to load the server information in the created
phase of the component. https://vuejs.org/guide/instance.html#Lifecycle-Diagram
Do you think this is possible? What do you recommend for this scenario? Maybe using transition hooks (http://router.vuejs.org/en/pipeline/hooks.html)?
Well, this data is important for SEO, so I don't think any JS will be useful, but.. dunno
Thanks in advance!
Hi,
it seems like the updateHead is not working again. using [email protected]
Hi
I’m using your repo to add description and title into each Vue page, but description doesn’t come up in to google search engine,
What do I do ?
ReferenceError: document is not defined
at /Users/isair/Workspace/mus-no-hanazono/node_modules/vue-head/vue-head.js:7:17
at Object.<anonymous> (/Users/isair/Workspace/mus-no-hanazono/node_modules/vue-head/vue-head.js:259:3)
document is not defined in server-side.
Do you have any plan to support ssr?
Is there support to remove all head things ( title,meta,scripts etc) when we change route?
as the new route will have diferrent or nothing of theese it would be better to exist the option to work also in components scope
Is there a way to replace the complete meta title? Setting title.inner now appends it to the current title.
I'm trying to figure out how to compose titles using variables defined in data
, but I don't seem to find the proper way of making this
work. I always get this error: TypeError: Cannot read property 'editing' of undefined
.
head: {
title: () => {
return {
inner: this.editing ? 'Edit Participant' : 'Create Participant',
};
},
},
data() {
return {
editing: false,
}
},
I've also tried like this, but no luck:
data: () => {
return {
editing: false
}
}
Hi,
I'm having trouble integrating vue-head with my project. The title shows up in my root single file component (although it's rendered 'My title |' unless I manually specify an empty separator) :
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'app',
head: {
title: {
inner: 'My title',
},
}
}
</script>
However using exactly the same format head definition in the various vue-router route components, I get 'undefined |'.
Any ideas?
Cheers
Hi! Sorry if this isn't really a bug, but I thought I'd see if you knew of a similar issue. This issue is when using Spark.
The default/main title is set in the head's HTML, like:
<title>My Site</title>
And the title defined through vue-head in a component. When the page is first loaded, the title displays correctly, combining 'My Site' with the title in the component.
However, when going to a different page (through vue-router
), it flashes the proper combined title for a second and then reverts back to just 'My Site'.
If I remove the default/main title from the head's HTML, it works as expected.
Any ideas? :) Thanks!
Given the following html, which implements favicons for multiple mobile browsers,
<link rel="shortcut icon" type="image/x-icon" href="~favicons/favicon.ico">
<link rel="icon" type="image/png" href="{% static 'logo-package.svg" sizes="16x16">
<link rel="icon" type="image/png" href="~favicons/favicon-16x16.png" sizes="16x16">
<link rel="icon" type="image/png" href="~favicons/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="~favicons/favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/png" href="~favicons/favicon-160x160.png" sizes="160x160">
<link rel="icon" type="image/png" href="~favicons/favicon-192x192.png" sizes="192x192">
<link rel="apple-touch-icon" sizes="57x57" href="~favicons/apple-touch-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="~favicons/apple-touch-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="~favicons/apple-touch-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="~favicons/apple-touch-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="~favicons/apple-touch-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="~favicons/apple-touch-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="~favicons/apple-touch-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="~favicons/apple-touch-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="~favicons/apple-touch-icon-180x180.png">
<meta name="msapplication-TileColor" content="orange">
<meta name="msapplication-TileImage" content="~favicons/mstile-144x144.png">
<meta name="msapplication-config" content="~favicons/browserconfig.xml">
How would I use vue-head to achieve a similar outcome?
in my component
head: {
script: [
{src: 'https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.js', body: true}
]
},
created: function () {
this.$on('okHead', function () {
var t = new SimpleMDE();
});
}
get SimpleMDE is not defined
how to get it work
Vue-head itself is working great when I hard code in the meta data for each component. Only issue is each component I pull in data from an HTTP request, each compoent from a differen api most the time.
So in a component this is what I have but at the point of the head:{}
object this.content
is not injected with the data. this.content
has the stuff I need, but it looks like after the head is called so I get all meta content as undefined
.
Here is the component script:
<script>
module.exports = {
data: function() {
return {
userLoggedIn: false,
title: 'Learn more about Leadership University',
content:[]
}
},
props:[
'user',
],
head: {
title: function () {
return {
inner: this.title
}
},
meta: function () {
return [
{ name: 'application-name', content: 'Leadership University' },
{ name: 'description', content: this.content.content_social_description, id: 'desc' },
// Twitter
{ name: 'twitter:title', content: this.content.content_name },
{ name: 'twitter:description', content: this.content.content_social_description},
// Google+ / Schema.org
{ itemprop: 'name', content: this.content.content_name },
{ itemprop: 'description', content: this.content.content_social_description },
// Facebook / Open Graph
{ property: 'og:title', content: this.content.content_name },
// with shorthand
{ p: 'og:image', c: this.content.content_image }
]
}
},
beforeCreate(){
//Get the content
this.$http.get('/ch_api_v2/api_content_getBySlug.php', {
params: {
slug: 'leadership_learnmore'
}
})
.then(response => {
this.content = response.data.content;
})
.catch(error => {
console.log(error);
});
},
mounted: function(){
},
methods:{
},
}
</script>
Can I add script like react-helmet ?
<Helmet
htmlAttributes={{"lang": "en", "amp": undefined}} // amp takes no value
title="My Title"
titleTemplate="MySite.com - %s"
defaultTitle="My Default Title"
base={{"target": "_blank", "href": "http://mysite.com/"}}
meta={[
{"name": "description", "content": "Helmet application"},
{"property": "og:type", "content": "article"}
]}
link={[
{"rel": "canonical", "href": "http://mysite.com/example"}
]}
script={[
{"src": "http://include.com/pathtojs.js", "type": "text/javascript"},
{"type": "application/ld+json", innerHTML: `{ "@context": "http://schema.org" }`}
]}
onChangeClientState={(newState) => console.log(newState)}
/>
I'm trying to share a dynamic content that I fetch from a REST API in my SPA. Now, I don't think facebook is fetching that title, description and image when we share the link. Is there any option for this?
Hi,
I've some issues with setting the title of the document while using your plugin. In my data object I've a default title, but when I change the the title after getting data from an ajax call, the title isn't changing in the <title> tag and in the browser tab, but vuejs did change the value of the title. I've managed to use a workaround with document.title
, but the source is not getting changed while the meta data does change.
Any idea why this issue occurs?
Data object
data: function(){
return{
slug: '',
project: '',
video: '',
page_title: 'Project',
meta_desc : '',
meta_tags : '',
checkMobile: this.$parent.checkMobile()
}
},
Head
head: {
title: function() {
return {
inner: this.page_title
}
},
meta: function () {
console.log('updating meta..');
return [
{ name: 'keywords', content: this.meta_tags, id: 'tags' },
{ name: 'description', content: this.meta_desc, id: 'desc' },
{ property: 'og:title', content: this.page_title, id: 'fb-title' },
{ property: 'og:description', content: this.meta_desc, id: 'fb-desc' },
{ property: 'twitter:title', content: this.page_title, id: 'twitter-title' },
{ property: 'twitter:description', content: this.meta_desc, id: 'twitter-desc' }
]
}
},
After calling the ajax call I set the title like this:
self.page_title = response.data.title;
self.$emit('updateHead');
the mounted work?
Right now seems like this package only allow user to set up complement at the beginning and the position of inner and complement is "inner | complement".
Is it possible that use a title like "complement | inner"?
Or switch the position of complement and inner?
Extend support for multiple tags of equals context.
Example:
<link rel="icon" href="favicon-32.png">
<link rel="icon" href="favicon-64.png">
<link rel="icon" href="favicon-128.png">
Website in question: https://nntin.github.io/pasteview/?paste=32z9wKpi
Source code: https://github.com/NNTin/pasteview
When posting the website to Discord or Twitter the information from the meta tags aren't retrieved. What am I doing wrong?
Lines 149 to 152 in 93b4d2e
These lines make the new(not exists in dom already) tags with ID do not add to document.
I am not sure if this is by design, but I think this behavior does not make sense.
Lines 156 to 159 in 93b4d2e
These lines make the updateHead event does not add any new tags. So we cannot add new tags asynchronously.
For example:
meta: function () {
var metaData = []
if (this.asyncData) { // this.asyncData is filled asynchronously.
metaData.push({ name: 'asyncData', content: this.asyncData })
} else {
// the following line cannot be omitted, otherwise the tag will not be appended to DOM.
metaData.push({ name: 'asyncData', content: '' })
}
console.log('metaData: %O', metaData)
return metaData
}
¡Thank you for making this lib!
I'm trying to make my app work with server side rendering, but it raises an exception for vue-head
Version: 2.0.6
ReferenceError: document is not defined
at C:\app\node_modules\vue-head\vue-head.js:7:17
at Object. (C:\app\node_modules\vue-head\vue-head.js:259:3)
at Module._compile (module.js:541:32)
at Object.Module._extensions..js (module.js:550:10)
at Module.load (module.js:458:32)
at tryModuleLoad (module.js:417:12)
at Function.Module._load (module.js:409:3)
at Module.require (module.js:468:17)
at require (internal/module.js:20:19)
at Object. (vue_ssr_bundle:7801:19)
Ops, i see that is an already planned feature, closing issue, soz.
I'm trying to apply dynamic data on my tags but i'm struggling since all data is going empty because the head won't wait the HTTP fetch the data:
export default {
[.....]
head: {
title () {
console.info(JSON.stringify(this.data))
return this.data.title
}
},
beforeRouteEnter (to, from, next) {
myService.fetch().then((response) => {
next((vm) => {
console.log('BeforeRouteEnter complete!')
vm.data = response.body
})
})
}
}
And my console output:
> {title: ''}
> BeforeRouteEnter complete!
Thank you all for the feedback.
Is already in production some improvements and new features.
When root and children route page switch can't trigger the title update。
I use the vue-head in my vue-router component like this:
head: {
script: [
{ type: 'text/javascript', src: 'http://xxx.com/xx.js' }
],
},
and I got a script in my body :
<script src="http://xxx.com/xx.js"></script>
when I back to this page, I got two:
<script src="http://xxx.com/xx.js"></script>
<script src="http://xxx.com/xx.js"></script>
every time I back to this page, the script element +1.
this make the page only work fine on the first entry. what can I do about this?
undo: false
It may already be possible to change the default title separator ("|"), but the documentation doesn't cover how to do so.
Please confirm whether or not this is possible, and how it can be done.
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.