@nuxtjs/seo 2.0.0-rc.16 → 2.0.0-rc.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.d.mts +4 -0
- package/dist/module.d.ts +4 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +12 -6
- package/dist/runtime/nuxt/composables/polyfills.d.ts +2 -2
- package/dist/runtime/nuxt/composables/useBreadcrumbItems.d.ts +1 -1
- package/dist/runtime/nuxt/composables/useBreadcrumbItems.js +4 -2
- package/dist/runtime/nuxt/logic/applyDefaults.d.ts +4 -1
- package/dist/runtime/nuxt/logic/applyDefaults.js +16 -14
- package/dist/runtime/nuxt/plugin/defaults.js +12 -3
- package/dist/runtime/nuxt/plugin/defaultsWaitI18n.js +23 -0
- package/package.json +9 -6
- package/dist/runtime/nuxt/plugin/defaultsWaitI18n.server.js +0 -14
- /package/dist/runtime/nuxt/plugin/{defaultsWaitI18n.server.d.ts → defaultsWaitI18n.d.ts} +0 -0
package/dist/module.d.mts
CHANGED
|
@@ -13,6 +13,10 @@ interface ModuleOptions {
|
|
|
13
13
|
* @default true
|
|
14
14
|
*/
|
|
15
15
|
automaticDefaults?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* When enabled, it will whitelist the query parameters that are allowed in the canonical URL.
|
|
18
|
+
*/
|
|
19
|
+
canonicalQueryWhitelist?: string[];
|
|
16
20
|
/**
|
|
17
21
|
* When enabled, it will redirect any request to the canonical domain (site url) using a 301 redirect on non-dev environments.
|
|
18
22
|
*
|
package/dist/module.d.ts
CHANGED
|
@@ -13,6 +13,10 @@ interface ModuleOptions {
|
|
|
13
13
|
* @default true
|
|
14
14
|
*/
|
|
15
15
|
automaticDefaults?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* When enabled, it will whitelist the query parameters that are allowed in the canonical URL.
|
|
18
|
+
*/
|
|
19
|
+
canonicalQueryWhitelist?: string[];
|
|
16
20
|
/**
|
|
17
21
|
* When enabled, it will redirect any request to the canonical domain (site url) using a 301 redirect on non-dev environments.
|
|
18
22
|
*
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -44,15 +44,21 @@ const module = defineNuxtModule({
|
|
|
44
44
|
await installNuxtSiteConfig();
|
|
45
45
|
for (const module of Modules)
|
|
46
46
|
await installModule(await resolvePath(module));
|
|
47
|
+
nuxt.options.runtimeConfig.public["nuxt-seo"] = {
|
|
48
|
+
canonicalQueryWhitelist: config.canonicalQueryWhitelist || [
|
|
49
|
+
"page",
|
|
50
|
+
"sort",
|
|
51
|
+
"filter",
|
|
52
|
+
"search",
|
|
53
|
+
"q",
|
|
54
|
+
"category",
|
|
55
|
+
"tag"
|
|
56
|
+
]
|
|
57
|
+
};
|
|
47
58
|
if (config.automaticDefaults) {
|
|
48
59
|
if (hasNuxtModule("@nuxtjs/i18n")) {
|
|
49
60
|
addPlugin({
|
|
50
|
-
src: resolve(`./runtime/nuxt/plugin/defaultsWaitI18n
|
|
51
|
-
mode: "server"
|
|
52
|
-
});
|
|
53
|
-
addPlugin({
|
|
54
|
-
src: resolve(`./runtime/nuxt/plugin/defaults`),
|
|
55
|
-
mode: "client"
|
|
61
|
+
src: resolve(`./runtime/nuxt/plugin/defaultsWaitI18n`)
|
|
56
62
|
});
|
|
57
63
|
} else {
|
|
58
64
|
addPlugin({
|
|
@@ -5,6 +5,6 @@ export declare function useI18n(): {
|
|
|
5
5
|
t: (_: string, fallback: string) => string;
|
|
6
6
|
te: (_: string) => boolean;
|
|
7
7
|
strategy: string;
|
|
8
|
-
defaultLocale: import("
|
|
9
|
-
locale: import("
|
|
8
|
+
defaultLocale: import("vue").Ref<any, any>;
|
|
9
|
+
locale: import("vue").Ref<any, any>;
|
|
10
10
|
};
|
|
@@ -82,5 +82,5 @@ export interface BreadcrumbItemProps extends NuxtUIBreadcrumbItem {
|
|
|
82
82
|
last: boolean;
|
|
83
83
|
};
|
|
84
84
|
}
|
|
85
|
-
export declare function useBreadcrumbItems(options?: BreadcrumbProps): import("
|
|
85
|
+
export declare function useBreadcrumbItems(options?: BreadcrumbProps): import("vue").ComputedRef<BreadcrumbItemProps[]>;
|
|
86
86
|
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { withoutTrailingSlash } from "ufo";
|
|
2
2
|
import { defu } from "defu";
|
|
3
|
+
import { fixSlashes } from "site-config-stack/urls";
|
|
3
4
|
import { pathBreadcrumbSegments } from "../../pure/breadcrumbs.js";
|
|
4
5
|
import {
|
|
5
6
|
computed,
|
|
@@ -10,7 +11,7 @@ import {
|
|
|
10
11
|
useRoute,
|
|
11
12
|
useRouter,
|
|
12
13
|
useSchemaOrg,
|
|
13
|
-
|
|
14
|
+
useSiteConfig
|
|
14
15
|
} from "#imports";
|
|
15
16
|
function withoutQuery(path) {
|
|
16
17
|
return path.split("?")[0];
|
|
@@ -26,6 +27,7 @@ export function useBreadcrumbItems(options = {}) {
|
|
|
26
27
|
canonical: true,
|
|
27
28
|
absolute: true
|
|
28
29
|
});
|
|
30
|
+
const siteConfig = useSiteConfig();
|
|
29
31
|
const items = computed(() => {
|
|
30
32
|
let rootNode = "/";
|
|
31
33
|
if (i18n) {
|
|
@@ -74,7 +76,7 @@ export function useBreadcrumbItems(options = {}) {
|
|
|
74
76
|
return item;
|
|
75
77
|
}).map((m) => {
|
|
76
78
|
if (m && m.to) {
|
|
77
|
-
m.to =
|
|
79
|
+
m.to = fixSlashes(siteConfig.trailingSlash, m.to);
|
|
78
80
|
if (m.to === rootNode && toValue(options.hideRoot))
|
|
79
81
|
return false;
|
|
80
82
|
}
|
|
@@ -1,38 +1,40 @@
|
|
|
1
|
+
import { stringifyQuery } from "ufo";
|
|
1
2
|
import {
|
|
2
3
|
computed,
|
|
3
4
|
createSitePathResolver,
|
|
4
5
|
useHead,
|
|
5
6
|
useRoute,
|
|
7
|
+
useRuntimeConfig,
|
|
6
8
|
useSeoMeta,
|
|
7
|
-
useServerHead,
|
|
8
9
|
useSiteConfig
|
|
9
10
|
} from "#imports";
|
|
10
|
-
export function applyDefaults() {
|
|
11
|
+
export function applyDefaults(i18n) {
|
|
12
|
+
const { canonicalQueryWhitelist } = useRuntimeConfig().public["nuxt-seo"];
|
|
11
13
|
const siteConfig = useSiteConfig();
|
|
12
14
|
const route = useRoute();
|
|
13
15
|
const resolveUrl = createSitePathResolver({ withBase: true, absolute: true });
|
|
14
|
-
const canonicalUrl = computed(() =>
|
|
16
|
+
const canonicalUrl = computed(() => {
|
|
17
|
+
const { query } = route;
|
|
18
|
+
const url = resolveUrl(route.path || "/").value || route.path;
|
|
19
|
+
const filteredQuery = Object.fromEntries(
|
|
20
|
+
Object.entries(query).filter(([key]) => canonicalQueryWhitelist.includes(key))
|
|
21
|
+
);
|
|
22
|
+
return Object.keys(filteredQuery).length ? `${url}?${stringifyQuery(filteredQuery)}` : url;
|
|
23
|
+
});
|
|
15
24
|
const minimalPriority = {
|
|
16
25
|
// give nuxt.config values higher priority
|
|
17
26
|
tagPriority: 101
|
|
18
27
|
};
|
|
19
28
|
useHead({
|
|
20
|
-
|
|
21
|
-
});
|
|
22
|
-
const locale = siteConfig.currentLocale || siteConfig.defaultLocale;
|
|
23
|
-
if (locale) {
|
|
24
|
-
useServerHead({
|
|
25
|
-
htmlAttrs: { lang: locale }
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
useHead({
|
|
29
|
+
htmlAttrs: { lang: i18n.locale },
|
|
29
30
|
templateParams: { site: siteConfig, siteName: siteConfig.name || "" },
|
|
30
|
-
titleTemplate: "%s %separator %siteName"
|
|
31
|
+
titleTemplate: "%s %separator %siteName",
|
|
32
|
+
link: [{ rel: "canonical", href: () => canonicalUrl.value }]
|
|
31
33
|
}, minimalPriority);
|
|
32
34
|
const seoMeta = {
|
|
33
35
|
ogType: "website",
|
|
34
36
|
ogUrl: () => canonicalUrl.value,
|
|
35
|
-
ogLocale: locale,
|
|
37
|
+
ogLocale: () => i18n.locale.value,
|
|
36
38
|
ogSiteName: siteConfig.name
|
|
37
39
|
};
|
|
38
40
|
if (siteConfig.description)
|
|
@@ -1,11 +1,20 @@
|
|
|
1
|
-
import { applyDefaults
|
|
1
|
+
import { applyDefaults } from "../logic/applyDefaults.js";
|
|
2
2
|
import {
|
|
3
|
-
defineNuxtPlugin
|
|
3
|
+
defineNuxtPlugin,
|
|
4
|
+
ref,
|
|
5
|
+
useSiteConfig
|
|
4
6
|
} from "#imports";
|
|
5
7
|
export default defineNuxtPlugin({
|
|
6
8
|
name: "nuxt-seo:defaults",
|
|
9
|
+
order: 999,
|
|
7
10
|
env: {
|
|
8
11
|
islands: false
|
|
9
12
|
},
|
|
10
|
-
setup
|
|
13
|
+
setup() {
|
|
14
|
+
const siteConfig = useSiteConfig();
|
|
15
|
+
const locale = ref(siteConfig.currentLocale || siteConfig.defaultLocale);
|
|
16
|
+
applyDefaults({
|
|
17
|
+
locale
|
|
18
|
+
});
|
|
19
|
+
}
|
|
11
20
|
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { applyDefaults } from "../logic/applyDefaults.js";
|
|
2
|
+
import { defineNuxtPlugin, ref, useSiteConfig } from "#imports";
|
|
3
|
+
export default defineNuxtPlugin({
|
|
4
|
+
name: "nuxt-seo:defaults",
|
|
5
|
+
env: {
|
|
6
|
+
islands: false
|
|
7
|
+
},
|
|
8
|
+
// we need to wait for the i18n plugin to run first
|
|
9
|
+
// @ts-expect-error dynamic
|
|
10
|
+
dependsOn: import.meta.server ? [
|
|
11
|
+
"nuxt-site-config:i18n"
|
|
12
|
+
] : [
|
|
13
|
+
"i18n:plugin"
|
|
14
|
+
],
|
|
15
|
+
setup(nuxtApp) {
|
|
16
|
+
const siteConfig = useSiteConfig();
|
|
17
|
+
const locale = ref(nuxtApp.$i18n?.locale?.value || siteConfig.currentLocale || siteConfig.defaultLocale);
|
|
18
|
+
nuxtApp.hook("i18n:localeSwitched", ({ newLocale }) => {
|
|
19
|
+
locale.value = newLocale;
|
|
20
|
+
});
|
|
21
|
+
applyDefaults({ locale });
|
|
22
|
+
}
|
|
23
|
+
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuxtjs/seo",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.0.0-rc.
|
|
4
|
+
"version": "2.0.0-rc.18",
|
|
5
|
+
"packageManager": "pnpm@9.5.0",
|
|
5
6
|
"description": "The all-in-one SEO layer for Nuxt 3.",
|
|
6
7
|
"author": {
|
|
7
8
|
"name": "Harlan Wilton",
|
|
@@ -33,7 +34,7 @@
|
|
|
33
34
|
"dependencies": {
|
|
34
35
|
"@nuxt/kit": "^3.12.3",
|
|
35
36
|
"@nuxtjs/robots": "^4.0.2",
|
|
36
|
-
"@nuxtjs/sitemap": "^
|
|
37
|
+
"@nuxtjs/sitemap": "^6.0.0-beta.1",
|
|
37
38
|
"defu": "^6.1.4",
|
|
38
39
|
"nuxt-link-checker": "^3.0.2",
|
|
39
40
|
"nuxt-og-image": "^3.0.0-rc.64",
|
|
@@ -47,15 +48,15 @@
|
|
|
47
48
|
"devDependencies": {
|
|
48
49
|
"@antfu/eslint-config": "^2.23.0",
|
|
49
50
|
"@nuxt/module-builder": "^0.8.1",
|
|
50
|
-
"@nuxt/schema": "^3.12.
|
|
51
|
-
"@nuxt/test-utils": "3.
|
|
51
|
+
"@nuxt/schema": "^3.12.4",
|
|
52
|
+
"@nuxt/test-utils": "^3.14.0",
|
|
52
53
|
"@nuxt/ui": "^2.17.0",
|
|
53
|
-
"@nuxtjs/i18n": "^8.3.
|
|
54
|
+
"@nuxtjs/i18n": "^8.3.3",
|
|
54
55
|
"bumpp": "^9.4.1",
|
|
55
56
|
"eslint": "^9.7.0",
|
|
56
57
|
"execa": "^9.3.0",
|
|
57
58
|
"nitropack": "^2.9.7",
|
|
58
|
-
"nuxt": "^3.12.
|
|
59
|
+
"nuxt": "^3.12.4",
|
|
59
60
|
"typescript": "5.4.5",
|
|
60
61
|
"vitest": "^2.0.3"
|
|
61
62
|
},
|
|
@@ -66,6 +67,8 @@
|
|
|
66
67
|
]
|
|
67
68
|
},
|
|
68
69
|
"resolutions": {
|
|
70
|
+
"@nuxt/schema": "3.12.3",
|
|
71
|
+
"nuxt": "3.12.3",
|
|
69
72
|
"shiki": "1.10.1"
|
|
70
73
|
},
|
|
71
74
|
"scripts": {
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { applyDefaults as setup } from "../logic/applyDefaults.js";
|
|
2
|
-
import { defineNuxtPlugin } from "#imports";
|
|
3
|
-
export default defineNuxtPlugin({
|
|
4
|
-
name: "nuxt-seo:defaults",
|
|
5
|
-
env: {
|
|
6
|
-
islands: false
|
|
7
|
-
},
|
|
8
|
-
// we need to wait for the i18n plugin to run first
|
|
9
|
-
dependsOn: [
|
|
10
|
-
// @ts-expect-error dynamic
|
|
11
|
-
"nuxt-site-config:i18n"
|
|
12
|
-
],
|
|
13
|
-
setup
|
|
14
|
-
});
|
|
File without changes
|