mirror of
https://github.com/tenrok/vue-meta.git
synced 2026-06-23 18:00:33 +03:00
fix zombie base tag + document supported props
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h5 align="center">
|
<h5 align="center">
|
||||||
Manage page meta info in Vue 2.0 components. SSR + Streaming supported. Inspired by <a href="https://github.com/nfl/react-helmet">react-helmet</a>
|
Manage page meta info in Vue 2.0 components. SSR + Streaming supported. Inspired by <a href="https://github.com/nfl/react-helmet">react-helmet</a>.
|
||||||
</h5>
|
</h5>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
@@ -59,6 +59,12 @@
|
|||||||
- [`titleTemplate` (String)](#titletemplate-string)
|
- [`titleTemplate` (String)](#titletemplate-string)
|
||||||
- [`htmlAttrs` (Object)](#htmlattrs-object)
|
- [`htmlAttrs` (Object)](#htmlattrs-object)
|
||||||
- [`bodyAttrs` (Object)](#bodyattrs-object)
|
- [`bodyAttrs` (Object)](#bodyattrs-object)
|
||||||
|
- [`base` (Object)](#base-object)
|
||||||
|
- [`meta` ([Object])](#meta-object)
|
||||||
|
- [`link` ([Object])](#link-object)
|
||||||
|
- [`style` ([Object])](#style-object)
|
||||||
|
- [`script` ([Object])](#script-object)
|
||||||
|
- [`noscript` ([Object])](#noscript-object)
|
||||||
- [How `metaInfo` is Resolved](#how-metainfo-is-resolved)
|
- [How `metaInfo` is Resolved](#how-metainfo-is-resolved)
|
||||||
- [Performance](#performance)
|
- [Performance](#performance)
|
||||||
- [How to prevent the update on the initial page render](#how-to-prevent-the-update-on-the-initial-page-render)
|
- [How to prevent the update on the initial page render](#how-to-prevent-the-update-on-the-initial-page-render)
|
||||||
@@ -150,13 +156,26 @@ app.get('*', (req, res) => {
|
|||||||
const context = { url: req.url }
|
const context = { url: req.url }
|
||||||
renderer.renderToString(context, (error, html) => {
|
renderer.renderToString(context, (error, html) => {
|
||||||
if (error) return res.send(error.stack)
|
if (error) return res.send(error.stack)
|
||||||
const { meta } = context
|
const {
|
||||||
const { title, htmlAttrs, bodyAttrs } = meta.inject()
|
title,
|
||||||
|
htmlAttrs,
|
||||||
|
bodyAttrs,
|
||||||
|
link,
|
||||||
|
style,
|
||||||
|
script,
|
||||||
|
noscript,
|
||||||
|
meta
|
||||||
|
} = context.meta.inject()
|
||||||
return res.send(`
|
return res.send(`
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html data-vue-meta-server-rendered ${htmlAttrs.text()}>
|
<html data-vue-meta-server-rendered ${htmlAttrs.text()}>
|
||||||
<head>
|
<head>
|
||||||
|
${meta.text()}
|
||||||
${title.text()}
|
${title.text()}
|
||||||
|
${link.text()}
|
||||||
|
${style.text()}
|
||||||
|
${script.text()}
|
||||||
|
${noscript.text()}
|
||||||
</head>
|
</head>
|
||||||
<body ${bodyAttrs.text()}>
|
<body ${bodyAttrs.text()}>
|
||||||
${html}
|
${html}
|
||||||
@@ -182,13 +201,26 @@ app.get('*', (req, res) => {
|
|||||||
renderStream.on('data', (chunk) => {
|
renderStream.on('data', (chunk) => {
|
||||||
if (firstChunk) {
|
if (firstChunk) {
|
||||||
firstChunk = false
|
firstChunk = false
|
||||||
const { meta } = context
|
const {
|
||||||
const { title, htmlAttrs, bodyAttrs } = meta.inject()
|
title,
|
||||||
|
htmlAttrs,
|
||||||
|
bodyAttrs,
|
||||||
|
link,
|
||||||
|
style,
|
||||||
|
script,
|
||||||
|
noscript,
|
||||||
|
meta
|
||||||
|
} = context.meta.inject()
|
||||||
res.write(`
|
res.write(`
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html data-vue-meta-server-rendered ${htmlAttrs.text()}>
|
<html data-vue-meta-server-rendered ${htmlAttrs.text()}>
|
||||||
<head>
|
<head>
|
||||||
|
${meta.text()}
|
||||||
${title.text()}
|
${title.text()}
|
||||||
|
${link.text()}
|
||||||
|
${style.text()}
|
||||||
|
${script.text()}
|
||||||
|
${noscript.text()}
|
||||||
</head>
|
</head>
|
||||||
<body ${bodyAttrs.text()}>
|
<body ${bodyAttrs.text()}>
|
||||||
`)
|
`)
|
||||||
@@ -343,6 +375,116 @@ Each **key:value** maps to the equivalent **attribute:value** of the `<body>` el
|
|||||||
<body bar="baz">Foo Bar</body>
|
<body bar="baz">Foo Bar</body>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### `base` (Object)
|
||||||
|
|
||||||
|
Maps to a newly-created `<base>` element, where object properties map to attributes.
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
metaInfo: {
|
||||||
|
base: { target: '_blank', href: '/' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<base target="_blank" href="/">
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `meta` ([Object])
|
||||||
|
|
||||||
|
Each item in the array maps to a newly-created `<meta>` element, where object properties map to attributes.
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
metaInfo: {
|
||||||
|
meta: [
|
||||||
|
{ charset: 'utf-8' },
|
||||||
|
{ name: 'viewport', content: 'width=device-width, initial-scale=1' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `link` ([Object])
|
||||||
|
|
||||||
|
Each item in the array maps to a newly-created `<link>` element, where object properties map to attributes.
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
metaInfo: {
|
||||||
|
link: [
|
||||||
|
{ rel: 'stylesheet', src: '/css/index.css' },
|
||||||
|
{ rel: 'favicon', src: 'favicon.ico' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<link rel="stylesheet" src="/css/index.css">
|
||||||
|
<link rel="favicon" src="favicon.ico">
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `style` ([Object])
|
||||||
|
|
||||||
|
Each item in the array maps to a newly-created `<style>` element, where object properties map to attributes.
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
metaInfo: {
|
||||||
|
style: [
|
||||||
|
{ cssText: '.foo { color: red }', type: 'text/css' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<style type="text/css">.foo { color: red }</style>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `script` ([Object])
|
||||||
|
|
||||||
|
Each item in the array maps to a newly-created `<script>` element, where object properties map to attributes.
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
metaInfo: {
|
||||||
|
sript: [
|
||||||
|
{ innerHTML: '{ "@context": "http://schema.org" }', type: 'application/ld+json' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script type="application/ld+json">{ "@context": "http://schema.org" }</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `noscript` ([Object])
|
||||||
|
|
||||||
|
Each item in the array maps to a newly-created `<noscript>` element, where object properties map to attributes.
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
metaInfo: {
|
||||||
|
nosript: [
|
||||||
|
{ innerHTML: 'This website requires JavaScript.' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<noscript>This website requires JavaScript.</noscript>
|
||||||
|
```
|
||||||
|
|
||||||
### How `metaInfo` is Resolved
|
### How `metaInfo` is Resolved
|
||||||
|
|
||||||
You can define a `metaInfo` property on any component in the tree. Child components that have `metaInfo` will recursively merge their `metaInfo` into the parent context, overwriting any duplicate properties. To better illustrate, consider this component heirarchy:
|
You can define a `metaInfo` property on any component in the tree. Child components that have `metaInfo` will recursively merge their `metaInfo` into the parent context, overwriting any duplicate properties. To better illustrate, consider this component heirarchy:
|
||||||
@@ -379,7 +521,7 @@ Add the `data-vue-meta-server-rendered` attribute to the `<html>` tag on the ser
|
|||||||
Here are some answers to some frequently asked questions.
|
Here are some answers to some frequently asked questions.
|
||||||
|
|
||||||
## How do I use component data in `metaInfo`?
|
## How do I use component data in `metaInfo`?
|
||||||
Specify a function instead of a property.
|
Specify a function instead of an object. It will need to return the same type as its definition.
|
||||||
|
|
||||||
**BlogPost.vue:**
|
**BlogPost.vue:**
|
||||||
```html
|
```html
|
||||||
@@ -405,7 +547,7 @@ Specify a function instead of a property.
|
|||||||
```
|
```
|
||||||
|
|
||||||
## How do I use component props in `metaInfo`?
|
## How do I use component props in `metaInfo`?
|
||||||
The same way you use data.
|
The same way you use data - specify a function instead of an object. It will need to return the same type as its definition.
|
||||||
|
|
||||||
**BlogPostWrapper.vue**
|
**BlogPostWrapper.vue**
|
||||||
```html
|
```html
|
||||||
|
|||||||
@@ -40,9 +40,7 @@ export default function updateClientMetaInfo (newInfo, $root) {
|
|||||||
// update tags
|
// update tags
|
||||||
for (let i = 0, len = tags.length; i < len; i++) {
|
for (let i = 0, len = tags.length; i < len; i++) {
|
||||||
const tag = tags[i]
|
const tag = tags[i]
|
||||||
if (newInfo[tag]) {
|
updateTags(tag, newInfo[tag], headTag)
|
||||||
updateTags(tag, newInfo[tag], headTag)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
htmlTag.removeAttribute(SERVER_RENDERED_ATTRIBUTE)
|
htmlTag.removeAttribute(SERVER_RENDERED_ATTRIBUTE)
|
||||||
|
|||||||
Reference in New Issue
Block a user