nuxt-link-checker 0.2.0 → 0.3.1
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/README.md +43 -8
- package/dist/module.d.ts +4 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +34 -2
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
<p align="center">
|
|
13
|
-
|
|
13
|
+
Identify and fix link issues for prerendered Nuxt 3 apps.
|
|
14
14
|
</p>
|
|
15
15
|
|
|
16
16
|
<p align="center">
|
|
@@ -18,7 +18,7 @@ Improve your sites SEO by identifying and fixing link issues in your Nuxt 3 app.
|
|
|
18
18
|
<tbody>
|
|
19
19
|
<td align="center">
|
|
20
20
|
<img width="800" height="0" /><br>
|
|
21
|
-
<i>Status:</i>
|
|
21
|
+
<i>Status:</i> Stable</b> <br>
|
|
22
22
|
<sup> Please report any issues 🐛</sup><br>
|
|
23
23
|
<sub>Made possible by my <a href="https://github.com/sponsors/harlan-zw">Sponsor Program 💖</a><br> Follow me <a href="https://twitter.com/harlan_zw">@harlan_zw</a> 🐦 • Join <a href="https://discord.gg/275MBUBvgP">Discord</a> for help</sub><br>
|
|
24
24
|
<img width="800" height="0" />
|
|
@@ -27,17 +27,16 @@ Improve your sites SEO by identifying and fixing link issues in your Nuxt 3 app.
|
|
|
27
27
|
</table>
|
|
28
28
|
</p>
|
|
29
29
|
|
|
30
|
-
ℹ️ Looking for a complete SEO solution? Check out [
|
|
30
|
+
ℹ️ Looking for a complete SEO solution? Check out [Nuxt SEO Kit](https://github.com/harlan-zw/nuxt-seo-kit).
|
|
31
31
|
|
|
32
32
|
## Features
|
|
33
33
|
|
|
34
34
|
- ✅ Discover broken links - 404s and internal redirects
|
|
35
|
+
- 🚩 Warnings for bad practice links - absolute instead of relative and wrong trailing slash
|
|
35
36
|
- 🕵️ Fail on build if broken links are found (optional)
|
|
36
37
|
|
|
37
38
|
## Install
|
|
38
39
|
|
|
39
|
-
⚠️ The module is in early access and only works when pre-rendering.
|
|
40
|
-
|
|
41
40
|
```bash
|
|
42
41
|
npm install --save-dev nuxt-link-checker
|
|
43
42
|
|
|
@@ -74,7 +73,6 @@ export default defineNuxtConfig({
|
|
|
74
73
|
})
|
|
75
74
|
```
|
|
76
75
|
|
|
77
|
-
|
|
78
76
|
### Set host (optional)
|
|
79
77
|
|
|
80
78
|
You'll need to provide the host of your site so that the crawler can resolve absolute URLs that may be internal.
|
|
@@ -86,12 +84,40 @@ export default defineNuxtConfig({
|
|
|
86
84
|
siteUrl: 'https://example.com',
|
|
87
85
|
},
|
|
88
86
|
// OR
|
|
89
|
-
|
|
87
|
+
linkChecker: {
|
|
90
88
|
host: 'https://example.com',
|
|
91
89
|
},
|
|
92
90
|
})
|
|
93
91
|
```
|
|
94
92
|
|
|
93
|
+
### Exclude URLs from throwing errors
|
|
94
|
+
|
|
95
|
+
You can exclude URLs from throwing errors by adding them to the `exclude` array.
|
|
96
|
+
|
|
97
|
+
For example, if you have an `/admin` route that is a separate application, you can ignore all `/admin` links with:
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
export default defineNuxtConfig({
|
|
101
|
+
linkChecker: {
|
|
102
|
+
exclude: [
|
|
103
|
+
'/admin/**'
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
})
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Disable errors on broken links
|
|
110
|
+
|
|
111
|
+
You can disable errors on broken links by setting `failOn404` to `false`.
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
export default defineNuxtConfig({
|
|
115
|
+
linkChecker: {
|
|
116
|
+
failOn404: false,
|
|
117
|
+
},
|
|
118
|
+
})
|
|
119
|
+
```
|
|
120
|
+
|
|
95
121
|
## Module Config
|
|
96
122
|
|
|
97
123
|
### `failOn404`
|
|
@@ -101,6 +127,15 @@ export default defineNuxtConfig({
|
|
|
101
127
|
|
|
102
128
|
If set to `true`, the build will fail if any broken links are found.
|
|
103
129
|
|
|
130
|
+
### `exclude`
|
|
131
|
+
|
|
132
|
+
- Type: `string[]`
|
|
133
|
+
- Default: `[]`
|
|
134
|
+
|
|
135
|
+
An array of URLs to exclude from the check.
|
|
136
|
+
|
|
137
|
+
This can be useful if you have a route that is not pre-rendered, but you know it will be valid.
|
|
138
|
+
|
|
104
139
|
### `host`
|
|
105
140
|
|
|
106
141
|
- Type: `string`
|
|
@@ -127,4 +162,4 @@ Whether internal links should have a trailing slash or not.
|
|
|
127
162
|
|
|
128
163
|
## License
|
|
129
164
|
|
|
130
|
-
MIT License ©
|
|
165
|
+
MIT License © 2023-PRESENT [Harlan Wilton](https://github.com/harlan-zw)
|
package/dist/module.d.ts
CHANGED
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { defineNuxtModule } from '@nuxt/kit';
|
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import { parseURL, hasProtocol } from 'ufo';
|
|
4
4
|
import { load } from 'cheerio';
|
|
5
|
+
import { toRouteMatcher, createRouter } from 'radix3';
|
|
5
6
|
|
|
6
7
|
const linkMap = {};
|
|
7
8
|
const EXT_REGEX = /\.[\da-z]+$/;
|
|
@@ -33,6 +34,33 @@ function extractLinks(html, from, { host, trailingSlash }) {
|
|
|
33
34
|
return links;
|
|
34
35
|
}
|
|
35
36
|
|
|
37
|
+
function createFilter(options = {}) {
|
|
38
|
+
const include = options.include || [];
|
|
39
|
+
const exclude = options.exclude || [];
|
|
40
|
+
if (include.length === 0 && exclude.length === 0)
|
|
41
|
+
return () => true;
|
|
42
|
+
return function(path) {
|
|
43
|
+
for (const v of [{ rules: exclude, result: false }, { rules: include, result: true }]) {
|
|
44
|
+
const regexRules = v.rules.filter((r) => r instanceof RegExp);
|
|
45
|
+
if (regexRules.some((r) => r.test(path)))
|
|
46
|
+
return v.result;
|
|
47
|
+
const stringRules = v.rules.filter((r) => typeof r === "string");
|
|
48
|
+
if (stringRules.length > 0) {
|
|
49
|
+
const routes = {};
|
|
50
|
+
for (const r of stringRules) {
|
|
51
|
+
if (r === path)
|
|
52
|
+
return v.result;
|
|
53
|
+
routes[r] = true;
|
|
54
|
+
}
|
|
55
|
+
const routeRulesMatcher = toRouteMatcher(createRouter({ routes, ...options }));
|
|
56
|
+
if (routeRulesMatcher.matchAll(path).length > 0)
|
|
57
|
+
return Boolean(v.result);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return include.length === 0;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
36
64
|
const invalidStatusCodes = [404, 302, 301, 307, 303];
|
|
37
65
|
const module = defineNuxtModule({
|
|
38
66
|
meta: {
|
|
@@ -47,12 +75,16 @@ const module = defineNuxtModule({
|
|
|
47
75
|
return {
|
|
48
76
|
host: nuxt.options.runtimeConfig.public?.siteUrl || "localhost",
|
|
49
77
|
trailingSlash: nuxt.options.runtimeConfig.public?.trailingSlash || false,
|
|
50
|
-
failOn404: true
|
|
78
|
+
failOn404: true,
|
|
79
|
+
exclude: []
|
|
51
80
|
};
|
|
52
81
|
},
|
|
53
82
|
setup(config, nuxt) {
|
|
54
83
|
if (nuxt.options.dev)
|
|
55
84
|
return;
|
|
85
|
+
const urlFilter = createFilter({
|
|
86
|
+
exclude: config.exclude
|
|
87
|
+
});
|
|
56
88
|
nuxt.hooks.hook("nitro:init", async (nitro) => {
|
|
57
89
|
const invalidRoutes = {};
|
|
58
90
|
nitro.hooks.hook("prerender:generate", async (ctx) => {
|
|
@@ -74,7 +106,7 @@ const module = defineNuxtModule({
|
|
|
74
106
|
...r,
|
|
75
107
|
statusCode: invalidRoutes[r.pathname] || 200
|
|
76
108
|
};
|
|
77
|
-
}).filter((r) => r.statusCode !== 200 || r.badTrailingSlash);
|
|
109
|
+
}).filter((r) => r.statusCode !== 200 || r.badTrailingSlash || r.badAbsolute).filter((r) => urlFilter(r.pathname));
|
|
78
110
|
if (brokenLinks.length) {
|
|
79
111
|
nitro.logger.log(chalk.gray(
|
|
80
112
|
` ${Number(++routeCount) === links.length - 1 ? "\u2514\u2500" : "\u251C\u2500"} ${chalk.white(route)}`
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-link-checker",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.1",
|
|
5
5
|
"packageManager": "pnpm@7.18.0",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"funding": "https://github.com/sponsors/harlan-zw",
|
|
@@ -29,20 +29,21 @@
|
|
|
29
29
|
"@nuxt/kit": "3.0.0",
|
|
30
30
|
"chalk": "^5.2.0",
|
|
31
31
|
"cheerio": "1.0.0-rc.12",
|
|
32
|
+
"radix3": "^1.0.0",
|
|
32
33
|
"ufo": "^1.0.1"
|
|
33
34
|
},
|
|
34
35
|
"devDependencies": {
|
|
35
|
-
"@antfu/eslint-config": "^0.34.
|
|
36
|
+
"@antfu/eslint-config": "^0.34.1",
|
|
36
37
|
"@nuxt/kit": "3.0.0",
|
|
37
38
|
"@nuxt/module-builder": "^0.2.1",
|
|
38
39
|
"@nuxt/test-utils": "3.0.0",
|
|
39
40
|
"@nuxtjs/eslint-config-typescript": "^12.0.0",
|
|
40
41
|
"bumpp": "^8.2.1",
|
|
41
|
-
"eslint": "8.
|
|
42
|
+
"eslint": "8.32.0",
|
|
42
43
|
"execa": "^6.1.0",
|
|
43
44
|
"nuxt": "^3.0.0",
|
|
44
|
-
"pathe": "^1.
|
|
45
|
-
"vitest": "^0.
|
|
45
|
+
"pathe": "^1.1.0",
|
|
46
|
+
"vitest": "^0.28.1"
|
|
46
47
|
},
|
|
47
48
|
"scripts": {
|
|
48
49
|
"lint": "eslint \"**/*.{ts,vue,json,yml}\" --fix",
|