From 5aa94ceea3e762b84ef09a9a7d0a8806c331d419 Mon Sep 17 00:00:00 2001 From: pimlie Date: Sun, 10 Mar 2019 21:58:13 +0100 Subject: [PATCH] chore: add docs site --- docs/.vuepress/config.js | 70 + docs/.vuepress/public/logo.png | Bin 0 -> 9641 bytes docs/README.md | 14 + docs/api/README.md | 470 +++ docs/faq/README.md | 76 + docs/faq/async-action.md | 22 + docs/faq/component-props.md | 55 + docs/faq/performance.md | 16 + docs/faq/prevent-initial.md | 12 + docs/guide/README.md | 36 + docs/guide/caveats.md | 39 + docs/guide/metainfo.md | 69 + docs/guide/special.md | 108 + docs/guide/ssr.md | 117 + docs/installation.md | 43 + package.json | 18 +- yarn.lock | 5100 +++++++++++++++++++++++++++++++- 17 files changed, 6173 insertions(+), 92 deletions(-) create mode 100644 docs/.vuepress/config.js create mode 100644 docs/.vuepress/public/logo.png create mode 100644 docs/README.md create mode 100644 docs/api/README.md create mode 100644 docs/faq/README.md create mode 100644 docs/faq/async-action.md create mode 100644 docs/faq/component-props.md create mode 100644 docs/faq/performance.md create mode 100644 docs/faq/prevent-initial.md create mode 100644 docs/guide/README.md create mode 100644 docs/guide/caveats.md create mode 100644 docs/guide/metainfo.md create mode 100644 docs/guide/special.md create mode 100644 docs/guide/ssr.md create mode 100644 docs/installation.md diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js new file mode 100644 index 0000000..220d480 --- /dev/null +++ b/docs/.vuepress/config.js @@ -0,0 +1,70 @@ +module.exports = { + locales: { + '/': { + lang: 'en-US', + title: 'Vue Meta', + description: 'Metadata manager for Vue.js' + }, + }, + serviceWorker: true, + theme: 'vue', + themeConfig: { + repo: 'nuxt/vue-meta', + docsDir: 'docs', + locales: { + '/': { + label: 'English', + selectText: 'Languages', + editLinkText: 'Edit this page on GitHub', + nav: [{ + text: 'Guide', + link: '/guide/' + }, { + text: 'API', + link: '/api/' + }, { + text: 'Release Notes', + link: 'https://github.com/nuxt/vue-meta/releases' + }], + sidebar: [ + '/installation.md', + '/', + { + title: 'Usage', + collapsable: false, + children: [ + '/guide/', + '/guide/ssr', + '/guide/metainfo', + '/guide/special', + '/guide/caveats', + ] + }, + { + title: 'FAQ', + collapsable: false, + children: [ + '/faq/', + '/faq/performance.md', + '/faq/prevent-initial.md', + '/faq/component-props.md', + '/faq/async-action.md', + ] + }, + /*{ + title: 'Advanced', + collapsable: false, + children: [ + '/guide/advanced/navigation-guards.md', + '/guide/advanced/meta.md', + '/guide/advanced/transitions.md', + '/guide/advanced/data-fetching.md', + '/guide/advanced/scroll-behavior.md', + '/guide/advanced/lazy-loading.md' + ] + }*/ + ] + }, + } + } +} diff --git a/docs/.vuepress/public/logo.png b/docs/.vuepress/public/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..1b1e1c973d6e1e19ef14a8141575828eee39d28c GIT binary patch literal 9641 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 ulAz(OCp_4*Fk7r-SYQ literal 0 HcmV?d00001 diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..dbf5d7f --- /dev/null +++ b/docs/README.md @@ -0,0 +1,14 @@ +vue-meta + +::: tip We need your help +We are working on defining the RFC for Vue Meta v3.0. It will be a ground-breaking release built from the ground up. + +We would like your help with this! Please visit the [Vue Meta v3.0 rfc](https://github.com/nuxt/rfcs/issues/19) and let us know your thoughts. +::: + +# Introduction +Vue Meta is a [Vue.js](https://vuejs.org) plugin that allows you to manage your app's metadata, much like [`react-helmet`](https://github.com/nfl/react-helmet) does for React. However, instead of setting your data as props passed to a proprietary component, you simply export it as part of your component's data using the `metaInfo` property. + +These properties, when set on a deeply nested component, will cleverly overwrite their parent components' `metaInfo`, thereby enabling custom info for each top-level view as well as coupling meta info directly to deeply nested subcomponents for more maintainable code. + +[Get started](/guide) or play with the [examples](https://github.com/nuxt/vue-meta/tree/master/examples) diff --git a/docs/api/README.md b/docs/api/README.md new file mode 100644 index 0000000..2d628e6 --- /dev/null +++ b/docs/api/README.md @@ -0,0 +1,470 @@ +--- +sidebar: auto +--- + +# API Reference + +## Plugin options + +### keyName +- type `string` +- default `metaInfo` + +The name of the component option that contains all the information that gets converted to the various meta tags & attributes for the page + +### attribute +- type `string` +- default `data-vue-meta` + +The name of the attribute vue-meta arguments on elements to know which it should manage and which it should ignore. + +### ssrAttribute +- type `string` +- default `data-vue-meta-server-rendered` + +The name of the attribute that is aded to the `html` tag to inform `vue-meta` that the server has already generated the meta tags for the initial render + +See [How to prevent update on page load](/faq/prevent-initial) + +### tagIDKeyName +- type `string` +- default `vmid` + +The property that tells vue-meta to overwrite (instead of append) an item in a tag list. +For example, if you have two `meta` tag list items that both have `vmid` of 'description', +then vue-meta will overwrite the shallowest one with the deepest one. + +### contentKeyName +- type `string` +- default `content` + +The key name for the content-holding property + +### metaTemplateKeyName +- type `string` +- default `template` + +The key name for possible meta templates + +### refreshOnceOnNavigation +- type `boolean` +- default `false` + +When `true` then vue-meta will pause updates once page navigation starts and resumes updates when navigation finishes (resuming also triggers an update). +This could both be a performance improvement as a possible fix for 'flickering' when you are e.g. replacing stylesheets + +## Plugin methods + +The `vue-meta` plugin injects a `$meta()` function in the Vue prototype which provides the following methods + +:::tip Note +`$meta()` is a function so we only need to insert it once in the `Vue.prototype`, but still use `this` to reference the component it was called from +::: + +### $meta().getOptions +- returns [`pluginOptions`](/api/#plugin-options) + +Could be used by third-party libraries who wish to interact with `vue-meta` + +### $meta().refresh +- returns [`metaInfo`](/api/#metaInfo-properties) + +Updates the current meta info with new meta info. +Useful when updating meta info as the result of an asynchronous action that resolves after the initial render takes place. + +### $meta().inject +- returns [`metaInfo`](/api/#metaInfo-properties) + +:::tip SSR only +`inject` is available in the server plugin only and is not available on the client +::: + +It returns a special `metaInfo` object where all keys have an object as value which contains a `text()` method for returning html code + +See [Rendering with renderToString](/guide/ssr.html#simple-rendering-with-rendertostring) for an example + +### $meta().pause +- arguments: + - refresh (type `boolean`, default `false`) +- returns `resume()` + +Pauses global metadata updates until either the returned resume method is called or [resume](/api/#meta-resume) + +### $meta().resume +- arguments: + - refresh (type `boolean`, default `false`) +- returns [`metaInfo`](/api/#metaInfo-properties) (optional) + +Resumes metadata updates after they have been paused. If `refresh` is `true` it immediately initiates a metadata update by calling [refresh](/api/#meta-refresh) + +## metaInfo properties + +::: tip Note +The documentation below uses `metaInfo` in the examples, please note that this keyName is [configurable](/api/#keyname) and could be different in your case +::: + +### title +- type `string` + +Maps to the inner-text value of the `` element. + +```js +{ + metaInfo: { + title: 'Foo Bar' + } +} +``` + +```html +<title>Foo Bar +``` + +### titleTemplate +- type `string | Function` + +The value of `title` will be injected into the `%s` placeholder in `titleTemplate` before being rendered. The original title will be available on `metaInfo.titleChunk`. + +```js +{ + metaInfo: { + title: 'Foo Bar', + titleTemplate: '%s - Baz' + } +} +``` + +```html +Foo Bar - Baz +``` + +The property can also be a function: + +```js +titleTemplate: (titleChunk) => { + // If undefined or blank then we don't need the hyphen + return titleChunk ? `${titleChunk} - Site Title` : 'Site Title'; +} +``` + +### htmlAttrs +### headAttrs +### bodyAttrs +- type `object` + +Each **key:value** maps to the equivalent **attribute:value** of the `` element. + +Since `v2.0` value can also be an `Array` + +```js +{ + metaInfo: { + htmlAttrs: { + lang: 'en', + amp: true + }, + bodyAttrs: { + class: ['dark-mode', 'mobile'] + } + } +} +``` + +```html + +Foo Bar +``` + +### base +- type `object` + +Maps to a newly-created `` element, where object properties map to attributes. + +```js +{ + metaInfo: { + base: { target: '_blank', href: '/' } + } +} +``` + +```html + +``` + +### meta +- type `collection` + +Each item in the array maps to a newly-created `` element, where object properties map to attributes. + +```js +{ + metaInfo: { + meta: [ + { charset: 'utf-8' }, + { name: 'viewport', content: 'width=device-width, initial-scale=1' } + ] + } +} +``` + +```html + + +``` + +#### Content templates + +Since `v1.5.0`, you can now set up meta templates that work similar to the titleTemplate: + +```js +{ + metaInfo: { + meta: [ + { charset: 'utf-8' }, + { + 'property': 'og:title', + 'content': 'Test title', + 'template': chunk => `${chunk} - My page`, //or as string template: '%s - My page', + 'vmid': 'og:title' + } + ] + } +} +``` + +```html + + +``` + +### link +- type `collection` + + +Each item in the array maps to a newly-created `` element, where object properties map to attributes. + +```js +{ + metaInfo: { + link: [ + { rel: 'stylesheet', href: '/css/index.css' }, + { rel: 'favicon', href: 'favicon.ico' } + ] + } +} +``` + +```html + + +``` + +### style +- type `object` + +Each item in the array maps to a newly-created ` +``` + +### script +- type `collection` + +Each item in the array maps to a newly-created ` +``` + +#### Add json or other raw data +::: warning +You have to disable sanitizers so the content of `innerHTML` won't be escaped. Please see [__dangerouslyDisableSanitizersByTagID](/api/#dangerouslydisablesanitizersbytagid) for more info on related risks +::: + +```js +{ + metaInfo: { + script: [{ + vmid: 'ldjson-schema', + innerHTML: '{ "@context": "http://schema.org" }', + type: 'application/ld+json' + }], + __dangerouslyDisableSanitizersByTagID: { + 'ldjson-schema': ['innerHTML'] + }, + } +} +``` + +```html + +``` +#### Special attribute: `body: true` + +If you e.g. wish to force delayed execution of a script or just want the script to be included in the `` of the page, add `body: true`. +Script tags with `body: true` are rendered just before `` + +```js +{ + metaInfo: { + script: [{ + innerHTML: 'console.log("I am in body");', + type: 'text/javascript', + body: true + }] + } +} +``` + +### noscript +- type `collection` + +Each item in the array maps to a newly-created `