2
0
mirror of https://github.com/tenrok/vue-meta.git synced 2026-06-17 14:20:34 +03:00

docs: update docs with new features (#416)

This commit is contained in:
Pim
2019-07-24 16:06:50 +02:00
committed by GitHub
parent 253108afac
commit 8f441899ef
8 changed files with 264 additions and 28 deletions
+35
View File
@@ -2,6 +2,8 @@
## Reactive variables in template functions
_Corresponding issue_: [#322](https://github.com/nuxt/vue-meta/issues/322)
Both [title](/api/#titletemplate) as [meta](/api/#content-templates) support using template function.
Due to how Vue determines reactivity it is not possible to use reactive variables directly in template functions
@@ -37,3 +39,36 @@ You need to assign the reactive variable to a local variable first for this to w
}
}
```
## Duplicated tags after hydration with SSR
_Corresponding issue_: [#404](https://github.com/nuxt/vue-meta/issues/404)
:::tip
Please read [Multiple Vue apps support](/guide/multiple-apps.html#ssr) as a prerequisite
:::
To optimize performance, VueMeta will only initialize for a Vue app when it finds a metaInfo property on any of the loaded components. That means if you render all your components by passing the component instance directly to the render function, Vue will only know of these components once the app gets mounted (see snippet below). And this means VueMeta is unable to find any metaInfo when it looks if its need to initialize in the `beforeCreate` hook and the appId will not be changed to the [ssrAppId](/api#ssrappid)
```js
/* this is an example of when metaInfo will only become available once the
* app is mounted and VueMeta will not correctly initialize the SSR app
*/
const myComponent = {
metaInfo: {
title: 'title'
}
}
export default App {
name: 'myApp',
render(h) {
return h(myComponent)
}
};
```
This will result in all the metaInfo properties of your ssr app to be rendered twice, once with [ssrAppId](/api#ssrappid) and once with appId `1`.
To prevent this, either make sure there is any metaInfo configured (on any component) when the `beforeCreate` hook runs. Alternative (but not recommended) you could set [ssrAppId](/api#ssrappid) to `1` as well.
+37
View File
@@ -0,0 +1,37 @@
# Multiple Vue apps support
VueMeta includes basic support for using multiple Vue-apps which each adds their own metaInfo properties to the same html page.
To keep track of which tag has been added by which Vue app, VueMeta stores an unique `appId` in the [data-vue-meta](/api/#attribute) attribute.
::: danger
Currently VueMeta only supports adding tags for multiple apps.
Adding [html](/api/#htmlattrs), [head](/api/#headattrs) or [body](/api/#bodyattrs) attributes is **not** supported. These will always be set to the values of the last app which triggered a metaInfo update.
Therefore it is recommended you should only set those attributes from one of your Vue apps
:::
## Client
On the client side the `appId` starts at `1` and is incremented by one for each subsequent Vue app
## SSR
For an SSR app which is served by a Node.js server, the appId would change for each request if we would increment it as on the client. Therefore we use the special [ssrAppId](/api#ssrappid) so the `appId` is constant for every request.
On hydration VueMeta will check if the Vue app was server-rendered and if so set it's appId to [ssrAppId](/api#ssrappid) as well.
## `vmid` support
::: warning
Support for cross-app vmid's might be insufficient for real world applications.
:::
It is possible to use cross app [vmid](/api/#tagidkeyname)'s with two important caveats:
- _The value of the last updated app is used_<br/>
Cross app vmid's only work on the client. This is implemented through the use of querySelectors, not by merging metaInfo objects. This means the last app which was refreshed determines the value that is used
- _There is no fallback to use the vmid of a previous app_<br/>
Given app1 and app2 both with a metaInfo property with vmid1, then when app2 removes its value for vmid1 there is no way to retrieve app1's value for vmid1 which means the element is removed
+13 -2
View File
@@ -37,7 +37,7 @@ app.get('*', (req, res) => {
} = context.meta.inject()
return res.send(`
<!doctype html>
<html data-vue-meta-server-rendered ${htmlAttrs.text()}>
<html ${htmlAttrs.text(true)}>
<head ${headAttrs.text()}>
${meta.text()}
${title.text()}
@@ -47,10 +47,22 @@ app.get('*', (req, res) => {
${noscript.text()}
</head>
<body ${bodyAttrs.text()}>
<!-- prepended metaInfo properties -->
${style.text({ pbody: true })}
${script.text({ pbody: true })}
${noscript.text({ pbody: true })}
<!-- app -->
${html}
<!-- webpack assets -->
<script src="/assets/vendor.bundle.js"></script>
<script src="/assets/client.bundle.js"></script>
<!-- appended metaInfo properties -->
${style.text({ body: true })}
${script.text({ body: true })}
${noscript.text({ body: true })}
</body>
</html>
`)
@@ -71,7 +83,6 @@ Notice the use of `{{{` to avoid double escaping. Be extremely cautious when you
## Inject metadata into page stream
A little more complex, but well worth it, is to instead stream your response. `vue-meta` supports streaming with no effort (on it's part :stuck_out_tongue_winking_eye:) thanks to Vue's clever `bundleRenderer` context injection:
**server.js**