Skip to content

Commit dd466d4

Browse files
committedOct 16, 2024
refactor!: migrate core features to nuxt-seo-utils
1 parent 5cbb29b commit dd466d4

13 files changed

+2006
-1989
lines changed
 

‎package.json

+5-8
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,14 @@
4444
},
4545
"dependencies": {
4646
"@nuxt/kit": "^3.13.2",
47-
"@nuxtjs/robots": "^4.1.7",
48-
"@nuxtjs/sitemap": "^6.1.1",
49-
"defu": "^6.1.4",
47+
"@nuxtjs/robots": "^4.1.8",
48+
"@nuxtjs/sitemap": "^6.1.2",
5049
"nuxt-link-checker": "^3.1.2",
51-
"nuxt-og-image": "^3.0.3",
50+
"nuxt-og-image": "^3.0.4",
5251
"nuxt-schema-org": "^3.4.0",
53-
"nuxt-seo-experiments": "^4.0.1",
52+
"nuxt-seo-utils": "^5.0.0",
5453
"nuxt-site-config": "^2.2.18",
55-
"nuxt-site-config-kit": "^2.2.18",
56-
"pkg-types": "^1.2.0",
57-
"ufo": "^1.5.4"
54+
"nuxt-site-config-kit": "^2.2.18"
5855
},
5956
"devDependencies": {
6057
"@antfu/eslint-config": "^3.7.3",

‎pnpm-lock.yaml

+1,903-1,381
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/const.ts

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
export interface NuxtSEOModule {
2+
slug: 'nuxt-seo' | 'site-config' | 'robots' | 'sitemap' | 'og-image' | 'link-checker' | 'seo-utils' | 'schema-org'
3+
label: string
4+
icon: string
5+
description: string
6+
repo: string
7+
npm: string
8+
}
9+
10+
export const NuxtSEO: NuxtSEOModule = {
11+
slug: 'nuxt-seo',
12+
label: 'Nuxt SEO - All-in-One',
13+
icon: 'i-carbon-settings-check',
14+
description: 'All the boring SEO work for Nuxt done.',
15+
repo: 'harlan-zw/nuxt-seo',
16+
npm: '@nuxtjs/seo',
17+
}
18+
19+
export const SiteConfigModule: NuxtSEOModule = {
20+
slug: 'site-config',
21+
label: 'Site Config',
22+
icon: 'i-carbon-settings-check',
23+
description: 'Powerful build and runtime shared site configuration for Nuxt modules.',
24+
repo: 'harlan-zw/nuxt-site-config',
25+
npm: 'nuxt-site-config',
26+
}
27+
28+
export const RobotsModule: NuxtSEOModule = {
29+
slug: 'robots',
30+
label: 'Robots',
31+
icon: 'i-carbon-bot',
32+
description: 'Tame the robots crawling and indexing your site with ease.',
33+
repo: 'nuxt-modules/robots',
34+
npm: '@nuxtjs/robots',
35+
}
36+
37+
export const SitemapModule: NuxtSEOModule = {
38+
slug: 'sitemap',
39+
label: 'Sitemap',
40+
icon: 'i-carbon-load-balancer-application',
41+
description: 'Powerfully flexible XML Sitemaps that integrate seamlessly.',
42+
repo: 'nuxt-modules/sitemap',
43+
npm: '@nuxtjs/seo',
44+
}
45+
46+
export const OgImageModule: NuxtSEOModule = {
47+
slug: 'og-image',
48+
label: 'OG Image',
49+
icon: 'i-carbon-image-search',
50+
description: 'Generate OG Images with Vue templates in Nuxt.',
51+
repo: 'nuxt-modules/og-image',
52+
npm: 'nuxt-og-image',
53+
}
54+
55+
export const LinkCheckerModule: NuxtSEOModule = {
56+
slug: 'link-checker',
57+
label: 'Link Checker',
58+
icon: 'i-carbon-cloud-satellite-link',
59+
description: 'Find and magically fix links that may be negatively effecting your SEO.',
60+
repo: 'harlan-zw/nuxt-link-checker',
61+
npm: 'nuxt-link-checker',
62+
}
63+
64+
export const SeoExperimentsModule: NuxtSEOModule = {
65+
slug: 'seo-utils',
66+
label: 'SEO Utils',
67+
icon: 'i-carbon-tools',
68+
description: 'SEO utilities to improve your Nuxt sites discoverability and shareability.',
69+
repo: 'harlan-zw/nuxt-seo-utils',
70+
npm: 'nuxt-seo-utils',
71+
}
72+
73+
export const SchemaOrgModule: NuxtSEOModule = {
74+
slug: 'schema-org',
75+
label: 'Schema.org',
76+
icon: 'i-carbon-chart-relationship',
77+
description: 'The quickest and easiest way to build Schema.org graphs.',
78+
repo: 'harlan-zw/nuxt-schema-org',
79+
npm: 'nuxt-schema-org',
80+
}
81+
82+
export const modules: NuxtSEOModule[] = [
83+
NuxtSEO,
84+
RobotsModule,
85+
SitemapModule,
86+
OgImageModule,
87+
SchemaOrgModule,
88+
LinkCheckerModule,
89+
SeoExperimentsModule,
90+
SiteConfigModule,
91+
]

‎src/module.ts

+7-176
Original file line numberDiff line numberDiff line change
@@ -1,202 +1,33 @@
11
import {
2-
addImports,
3-
addPlugin,
4-
addServerHandler,
5-
createResolver,
62
defineNuxtModule,
7-
hasNuxtModule,
83
installModule,
9-
useLogger,
4+
resolvePath,
105
} from '@nuxt/kit'
11-
import { colors } from 'consola/utils'
12-
import { installNuxtSiteConfig } from 'nuxt-site-config-kit'
13-
import { $fetch } from 'ofetch'
14-
import { readPackageJSON } from 'pkg-types'
6+
import { modules } from './const'
157

168
export interface ModuleOptions {
17-
/**
18-
* Will ensure a title is always set by providing a fallback title based on the casing the last slug segment.
19-
*
20-
* @default true
21-
*/
22-
fallbackTitle?: boolean
23-
/**
24-
* Will set up a number of defaults for meta tags and Schema.org, if the modules and config are available.
25-
*
26-
* @default true
27-
*/
28-
automaticDefaults?: boolean
29-
/**
30-
* When enabled, it will whitelist the query parameters that are allowed in the canonical URL.
31-
*/
32-
canonicalQueryWhitelist?: string[]
33-
/**
34-
* When enabled, it will redirect any request to the canonical domain (site url) using a 301 redirect on non-dev environments.
35-
*
36-
* E.g if the site url is 'www.example.com' and the user visits 'example.com',
37-
* they will be redirected to 'www.example.com'.
38-
*
39-
* This is useful for SEO as it prevents duplicate content and consolidates page rank.
40-
*
41-
* @default false
42-
*/
43-
redirectToCanonicalSiteUrl?: boolean
449
/**
4510
* Whether the module should be loaded.
4611
*/
4712
enabled: boolean
48-
/**
49-
* Whether the debugging mode should be enabled.
50-
*
51-
* @default `nuxt.options.debug`
52-
*/
53-
debug: boolean
54-
/**
55-
* Whether the Nuxt SEO splash should be shown when Nuxt is started.
56-
*
57-
* @default `nuxt.options.dev`
58-
*/
59-
splash: boolean
6013
}
6114

62-
const Modules = [
63-
'@nuxtjs/robots',
64-
'@nuxtjs/sitemap',
65-
'nuxt-og-image',
66-
'nuxt-schema-org',
67-
'nuxt-seo-experiments',
68-
'nuxt-link-checker',
69-
]
70-
7115
export default defineNuxtModule<ModuleOptions>({
7216
meta: {
7317
name: 'nuxtseo',
7418
compatibility: {
7519
nuxt: '>=3.7.0',
7620
bridge: false,
7721
},
78-
configKey: 'seo',
7922
},
80-
defaults(nuxt) {
81-
return {
82-
enabled: true,
83-
debug: nuxt.options.debug,
84-
redirectToCanonicalSiteUrl: false,
85-
splash: false, // nuxt.options.dev, - figure out a solution for this in the future
86-
automaticDefaults: true,
87-
fallbackTitle: true,
88-
}
23+
defaults: {
24+
enabled: true,
8925
},
9026
async setup(config, nuxt) {
91-
const { resolve, resolvePath } = createResolver(import.meta.url)
92-
const { name, version } = await readPackageJSON(resolve('../package.json'))
93-
const logger = useLogger(name)
94-
logger.level = config.debug ? 4 : 3
95-
if (config.enabled === false) {
96-
logger.debug('The module is disabled, skipping setup.')
27+
if (!config.enabled) {
9728
return
9829
}
99-
100-
await installNuxtSiteConfig()
101-
102-
// TODO disable modules if SSR is disabled
103-
// if (!nuxt.options.ssr) {
104-
// nuxt.options.schemaOrg = defu({ enabled: false}, nuxt.options.schemaOrg)
105-
// nuxt.options.ogImage = defu({ enabled: false}, nuxt.options.ogImage)
106-
// logger.warn('SSR is required for Nuxt OG Image and Nuxt Schema.org, disabling them.')
107-
// }
108-
109-
for (const module of Modules)
110-
await installModule(await resolvePath(module))
111-
112-
nuxt.options.runtimeConfig.public['nuxt-seo'] = {
113-
canonicalQueryWhitelist: config.canonicalQueryWhitelist || [
114-
'page',
115-
'sort',
116-
'filter',
117-
'search',
118-
'q',
119-
'category',
120-
'tag',
121-
],
122-
}
123-
124-
if (config.automaticDefaults) {
125-
// i18n complicates things, we need to run the server plugin at the right time, client is fine
126-
if (hasNuxtModule('@nuxtjs/i18n')) {
127-
addPlugin({
128-
src: resolve(`./runtime/nuxt/plugin/defaultsWaitI18n`),
129-
})
130-
}
131-
else {
132-
addPlugin({
133-
src: resolve(`./runtime/nuxt/plugin/defaults`),
134-
})
135-
}
136-
}
137-
if (config.fallbackTitle) {
138-
addPlugin({
139-
src: resolve('./runtime/nuxt/plugin/titles'),
140-
})
141-
}
142-
143-
if (!hasNuxtModule('@nuxtjs/i18n')) {
144-
addImports({
145-
from: resolve(`./runtime/nuxt/composables/polyfills`),
146-
name: 'useI18n',
147-
})
148-
}
149-
150-
addImports({
151-
from: resolve(`./runtime/nuxt/composables/useBreadcrumbItems`),
152-
name: 'useBreadcrumbItems',
153-
})
154-
155-
// TODO blocked by https://github.com/nuxt/nuxt/issues/25532
156-
// if (nuxt.options.experimental?.defaults?.nuxtLink && typeof nuxt.options.experimental?.defaults?.nuxtLink?.trailingSlash == 'undefined')
157-
// nuxt.options.experimental.defaults.nuxtLink.trailingSlash = siteConfig.trailingSlash ? 'append' : 'remove'
158-
159-
// if user disables certain modules we need to pollyfill the imports
160-
const polyfills: Record<string, string[]> = {
161-
schemaOrg: ['useSchemaOrg', 'defineWebSite', 'defineWebPage'],
162-
}
163-
for (const [module, composables] of Object.entries(polyfills)) {
164-
if (nuxt.options[module as keyof typeof nuxt.options]?.enable === false) {
165-
composables.forEach((name) => {
166-
// add pollyfill
167-
addImports({
168-
from: resolve('./runtime/nuxt/composables/polyfills'),
169-
name,
170-
})
171-
})
172-
}
173-
}
174-
nuxt.options.experimental.headNext = true
175-
176-
// add redirect middleware
177-
if (!nuxt.options.dev && config.redirectToCanonicalSiteUrl) {
178-
addServerHandler({
179-
handler: resolve('./runtime/nitro/middleware/redirect'),
180-
middleware: true,
181-
})
182-
}
183-
184-
if (config.splash && !version!.includes('rc') && nuxt.options.dev) {
185-
logger.log('')
186-
let latestTag = `v${version}`
187-
latestTag = (await $fetch<any>('https://ungh.unjs.io/repos/harlan-zw/nuxt-seo/releases/latest', {
188-
timeout: 2000,
189-
})
190-
.catch(() => {
191-
return { release: { tag: `v${version}` } }
192-
})).release.tag
193-
const upToDate = latestTag === `v${version}`
194-
logger.log(`${colors.green('Nuxt SEO')} ${colors.yellow(`v${version}`)} ${colors.gray(`by ${colors.underline('@harlan_zw')}`)}`)
195-
if (!upToDate)
196-
logger.log(`${colors.gray(' ├─ ')}🎉 New version available!${colors.gray(` Run ${colors.underline(`npm i @nuxtjs/seo@${latestTag}`)} to update.`)}`)
197-
198-
logger.log(colors.dim(' └─ 🧪 Help get Nuxt SEO stable by providing feedback https://github.com/harlan-zw/nuxt-seo/discussions/108'))
199-
logger.log('')
200-
}
30+
for (const module of modules)
31+
await installModule(await resolvePath(module.npm), {}, nuxt)
20132
},
20233
})

‎src/runtime/nitro/middleware/redirect.ts

-23
This file was deleted.

‎src/runtime/nitro/tsconfig.json

-3
This file was deleted.

‎src/runtime/nuxt/composables/polyfills.ts

-18
This file was deleted.

‎src/runtime/nuxt/composables/useBreadcrumbItems.ts

-203
This file was deleted.

‎src/runtime/nuxt/logic/applyDefaults.ts

-64
This file was deleted.

‎src/runtime/nuxt/plugin/defaults.ts

-22
This file was deleted.

‎src/runtime/nuxt/plugin/defaultsWaitI18n.ts

-27
This file was deleted.

‎src/runtime/nuxt/plugin/titles.ts

-39
This file was deleted.

‎src/runtime/pure/breadcrumbs.ts

-25
This file was deleted.

0 commit comments

Comments
 (0)
Please sign in to comment.