nuxt-seo
Advanced tools
Comparing version 1.0.0 to 1.1.0
@@ -13,3 +13,3 @@ import Vue from 'vue' | ||
/* eslint-disable camelcase */ | ||
import nuxt_plugin_NuxtSeo_15ac185a from 'nuxt_plugin_NuxtSeo_15ac185a' // Source: ./Nuxt-Seo.js (mode: 'all') | ||
import nuxt_plugin_NuxtSeo_b98f85e8 from 'nuxt_plugin_NuxtSeo_b98f85e8' // Source: ./Nuxt-Seo.js (mode: 'all') | ||
@@ -136,4 +136,4 @@ /* eslint-enable camelcase */ | ||
if (typeof nuxt_plugin_NuxtSeo_15ac185a === 'function') { | ||
await nuxt_plugin_NuxtSeo_15ac185a(app.context, inject) | ||
if (typeof nuxt_plugin_NuxtSeo_b98f85e8 === 'function') { | ||
await nuxt_plugin_NuxtSeo_b98f85e8(app.context, inject) | ||
} | ||
@@ -140,0 +140,0 @@ |
@@ -8,25 +8,85 @@ const path = require('path') | ||
charset: 'utf-8', | ||
title: 'TITLE', //Rec: Replace 'and' ~> '&' & 'or' ~> '/' | ||
lang: 'en', | ||
language: 'English', | ||
image: '', | ||
description: '', //Rec: 160max | ||
keywords: [], | ||
type: '', //http://ogp.me/#types | ||
name: '', | ||
url: '', | ||
author: '' | ||
templateTitle: '%title%', | ||
title: 'Title', | ||
name: false, | ||
description: false | ||
} | ||
const create = (options, inputMeta) => { | ||
const arrayToString = (value) => { | ||
if (value && value.length > 0) { | ||
if (Array.isArray(value)) { | ||
return value.join(', ') | ||
} | ||
return value | ||
const allMetas = { | ||
charset: {content: false}, | ||
lang: {content: false}, | ||
language: {content: false}, | ||
copyright: {content: true}, | ||
name: {content: true}, | ||
title: {content: true}, | ||
subtitle: {content: true}, | ||
author: {content: true}, | ||
replyTo: {id: 'reply-to', content: true}, | ||
description: {content: true}, | ||
keywords: {content: true}, | ||
url: {content: true}, | ||
noindex: {id: 'robots', content: true}, | ||
openGraph: { | ||
id: 'og', | ||
name: {id: 'site_name', default: 'name', content: true}, | ||
title: {default: 'title', content: true}, | ||
description: {default: 'description', content: true}, | ||
locale: {default: 'lang', content: true}, | ||
url: {default: 'url', content: true}, | ||
type: {content: true}, | ||
profile: { | ||
id: 'profile', | ||
firstName: {fullId: 'profile:first_name', content: true}, | ||
lastName: {fullId: 'profile:last_name', content: true}, | ||
username: {fullId: 'profile:username', content: true}, | ||
gender: {fullId: 'profile:gender', content: true} | ||
}, | ||
article: { | ||
publishedTime: {fullId: 'article:published_time', content: true}, | ||
modifiedTime: {fullId: 'article:modified_time', content: true}, | ||
expirationTime: {fullId: 'article:expiration_time', content: true}, | ||
author: {fullId: 'article:author', content: true}, | ||
section: {fullId: 'article:section', content: true}, | ||
tag: {fullId: 'article:tag', content: true} | ||
}, | ||
image: { | ||
id: 'image', | ||
content: true, | ||
url: {fullId: 'og:image', content: true}, | ||
width: {content: true}, | ||
height: {content: true}, | ||
alt: {content: true} | ||
}, | ||
price: { | ||
id: 'price', | ||
currency: {content: true}, | ||
amount: {content: true} | ||
} | ||
return false | ||
}, | ||
facebook: { | ||
id: 'fb', | ||
appId: {id: 'app_id', content: true}, | ||
pageId: {id: 'page_id', content: true} | ||
}, | ||
twitter: { | ||
id: 'twitter', | ||
title: {default: 'title', content: true}, | ||
description: {default: 'description', content: true}, | ||
card: {content: true}, | ||
type: {id: 'card', content: true}, | ||
site: {content: true}, | ||
creator: {content: true} | ||
} | ||
} | ||
allMetas.og = allMetas.openGraph | ||
allMetas.fb = allMetas.facebook | ||
const createTitle = (options = {}) => { | ||
return options.templateTitle.replace(/%title%/g, options.title) | ||
} | ||
const createMeta = (options = {}, inputMeta = [], template = {}) => { | ||
const outputMeta = [] | ||
const getMetaKey = (input) => { | ||
@@ -36,2 +96,6 @@ const keys = Object.keys(input) | ||
return input.hid | ||
} else if (input.key) { | ||
return input.key | ||
} else if (input.property) { | ||
return input.property | ||
} else if (input.name) { | ||
@@ -42,92 +106,70 @@ return input.name | ||
} | ||
const findAndRemove = (id) => { | ||
inputMeta = inputMeta.filter((meta) => { | ||
return getMetaKey(meta) != id | ||
}) | ||
} | ||
const generate = (metas, opts, id = '') => { | ||
Object.keys(metas).map((k) => { | ||
const meta = {...metas[k]} | ||
if (meta.fullId) { | ||
meta.id = meta.fullId | ||
} else if (!meta.id) { | ||
meta.id = id + k | ||
} else { | ||
meta.id = id + meta.id | ||
} | ||
let meta = [] | ||
//Basic HTML Meta | ||
meta.push({ lang: options.lang }) | ||
meta.push({ language: options.language }) | ||
meta.push({ | ||
name: 'description', | ||
content: options.description | ||
}) | ||
meta.push({ | ||
name: 'keywords', | ||
content: arrayToString(options.keywords) | ||
}) | ||
meta.push({ | ||
name: 'author', | ||
content: arrayToString(options.author) | ||
}) | ||
if (opts[k]) { | ||
meta.value = opts[k] | ||
} else if (meta.default && options[meta.default]) { | ||
meta.value = options[meta.default] | ||
} else { | ||
return | ||
} | ||
//Basic The Open Graph protocol | ||
meta.push({ | ||
name: 'og:title', | ||
content: options.title | ||
}) | ||
meta.push({ | ||
name: 'og:type', | ||
content: options.type | ||
}) | ||
meta.push({ | ||
name: 'og:url', | ||
content: options.url | ||
}) | ||
meta.push({ | ||
name: 'og:image', | ||
content: options.image | ||
}) | ||
meta.push({ | ||
name: 'og:site_name', | ||
content: options.name | ||
}) | ||
meta.push({ | ||
name: 'og:description', | ||
content: options.description | ||
}) | ||
if (typeof meta.value == 'object') { | ||
return generate(meta, meta.value, meta.id+':') | ||
} else if (meta.content) { | ||
findAndRemove(meta.id) | ||
//Basic Twitter Meta | ||
meta.push({ | ||
name: 'twitter:title', | ||
content: options.title | ||
}) | ||
meta.push({ | ||
name: 'twitter:url', | ||
content: options.url | ||
}) | ||
if (Array.isArray(meta.value)) { | ||
meta.value = meta.value.join(',') | ||
} | ||
meta = meta.filter((m) => { | ||
if (typeof m.lang != 'undefined') { | ||
return m.lang | ||
} else if (typeof m.language != 'undefined') { | ||
return m.language | ||
} else if (typeof m.content == 'string') { | ||
return m.content != '' | ||
} else if (typeof m.content == 'undefined') { | ||
return true | ||
} | ||
return m.content | ||
}) | ||
meta = meta.map((m) => { | ||
if (typeof m.content == 'string') { | ||
m.property = m.name | ||
m.hid = m.name | ||
} | ||
return m | ||
}) | ||
const metaKeys = meta.map((m) => { | ||
return getMetaKey(m) | ||
}).filter(k => k) //remove false, undefined & null | ||
const inputWithoutDup = inputMeta.filter((m) => { | ||
return !metaKeys.includes(getMetaKey(m)) //Replace HTM Meta -> Nuxt Seo Meta | ||
}) | ||
return [ | ||
...meta, | ||
...inputWithoutDup | ||
] | ||
meta.value = meta.value.toString() | ||
if (!meta.value || meta.value.length <= 0) { | ||
return | ||
} | ||
outputMeta.push({ | ||
hid: meta.id, | ||
key: meta.id, | ||
property: meta.id, | ||
name: meta.id, | ||
content: meta.value | ||
}) | ||
} else if (meta.id) { | ||
findAndRemove(meta.id) | ||
outputMeta.push({ | ||
[meta.id]: meta.value | ||
}) | ||
} | ||
}) | ||
} | ||
generate(template, options) | ||
return outputMeta | ||
} | ||
module.exports = function (moduleOptions) { | ||
if (!moduleOptions.meta) { | ||
moduleOptions.meta = {} | ||
} | ||
this.nuxt.hook('build:before', () => { | ||
const template = { | ||
...allMetas, | ||
...this.options.meta, | ||
...moduleOptions.meta | ||
} | ||
delete moduleOptions.meta | ||
const options = { | ||
@@ -141,11 +183,13 @@ ...defaults, | ||
options.title = this.options.head.title | ||
} else { | ||
this.options.head.title = options.title | ||
} | ||
this.options.head.meta = create(options, this.options.head.meta) | ||
this.options.title = createTitle(options) | ||
this.options.head.meta = createMeta(options, this.options.head.meta, template) | ||
const pluginOptions = { | ||
moduleOptions: options, | ||
template: template, | ||
func: { | ||
create | ||
createMeta, | ||
createTitle | ||
} | ||
@@ -165,1 +209,5 @@ } | ||
module.exports.meta = require('../package.json') | ||
module.exports.defaults = defaults | ||
module.exports.createTitle = createTitle | ||
module.exports.createMeta = createMeta | ||
module.exports.template = allMetas |
@@ -6,3 +6,3 @@ { | ||
"preferGlobal": false, | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"description": "SEO / HTML Meta Tags Module for Nuxt.js", | ||
@@ -60,2 +60,3 @@ "author": { | ||
"ava": "1.4.1", | ||
"got": "9.6.0", | ||
"nuxt": "2.6.2", | ||
@@ -62,0 +63,0 @@ "vue": "2.6.10" |
@@ -39,2 +39,3 @@ # Nuxt SEO | ||
title: '<title default>', | ||
templateTitle: '%name% - %title%', | ||
description: '<description default' | ||
@@ -48,2 +49,6 @@ //... | ||
#### `charset` | ||
- Default: `utf-8` | ||
- Type: String | ||
#### `name` | ||
@@ -53,6 +58,2 @@ - Default: `false` | ||
#### `charset` | ||
- Default: `utf-8` | ||
- Type: String | ||
#### `title` | ||
@@ -62,2 +63,10 @@ - Default: `TITLE` | ||
#### `description` | ||
- Default: `false` | ||
- Type: String | ||
#### `keywords` | ||
- Default: `[]` | ||
- Type: Array[...keywords] || String | ||
#### `lang` | ||
@@ -75,18 +84,10 @@ - Default: `en` | ||
#### `description` | ||
### `author` | ||
- Default: `false` | ||
- Type: String | ||
- Type: Array[name, email || site] || String | ||
#### `keywords` | ||
- Default: `[]` | ||
- Type: Array[...keywords] || String | ||
#### `type` | ||
#### `openGraph.type` | ||
- Default: `false` | ||
- Types: [ogp.me/#types](http://ogp.me/#types) | ||
### `author` | ||
- Default: `false` | ||
- Type: Array[name, email || site] || String | ||
#### `url` | ||
@@ -96,2 +97,5 @@ - Default: `false` | ||
### `{...all}` | ||
`charset`, `lang`, `language`, `copyright`, `name`, `title`, `subtitle`, `author`, `replyTo`, `description`, `keywords`, `url`, `noindex`, `openGraph.name`, `openGraph.title`, `openGraph.description`, `openGraph.locale`, `openGraph.url`, `openGraph.type`, `openGraph.profile.firstName`, `openGraph.profile.lastName`, `openGraph.profile.username`, `openGraph.profile.gender`, `openGraph.profile`, `openGraph.article.publishedTime`, `openGraph.article.modifiedTime`, `openGraph.article.expirationTime`, `openGraph.article.author`, `openGraph.article.section`, `openGraph.article.tag`, `openGraph.article`, `openGraph.image.url`, `openGraph.image.width`, `openGraph.image.height`, `openGraph.image.alt`, `openGraph.image`, `openGraph.price.currency`, `openGraph.price.amount`, `openGraph.price`, `openGraph`, `facebook.appId`, `facebook.pageId`, `facebook`, `twitter.title`, `twitter.description`, `twitter.card`, `twitter.type`, `twitter.site`, `twitter.creator`, `twitter`, `og.name`, `og.title`, `og.description`, `og.locale`, `og.url`, `og.type`, `og.profile.firstName`, `og.profile.lastName`, `og.profile.username`, `og.profile.gender`, `og.profile`, `og.article.publishedTime`, `og.article.modifiedTime`, `og.article.expirationTime`, `og.article.author`, `og.article.section`, `og.article.tag`, `og.article`, `og.image.url`, `og.image.width`, `og.image.height`, `og.image.alt`, `og.image`, `og.price.currency`, `og.price.amount`, `og.price`, `og`, `fb.appId`, `fb.pageId`, `fb` | ||
### Vue Context | ||
@@ -112,5 +116,2 @@ - `asyncData: function({ seo }) { seo(options) }` | ||
}) | ||
}, | ||
head: { | ||
//title: 'Home Page' | ||
} | ||
@@ -136,2 +137,3 @@ } | ||
- [ava](https://ghub.io/ava): Testing can be a drag. AVA helps you get it done. | ||
- [got](https://ghub.io/got): Simplified HTTP requests | ||
- [nuxt](https://ghub.io/nuxt): A minimalistic framework for server-rendered Vue.js applications (inspired by Next.js) | ||
@@ -138,0 +140,0 @@ - [vue](https://ghub.io/vue): Reactive, component-oriented view layer for modern web interfaces. |
16907
334
141
4
5