nuxt-link-checker 0.1.6 → 0.2.0

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 CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
 
12
12
  <p align="center">
13
- Improve your sites SEO by identifying and fixing link issues in your Nuxt v3 app.
13
+ Improve your sites SEO by identifying and fixing link issues in your Nuxt 3 app.
14
14
  </p>
15
15
 
16
16
  <p align="center">
@@ -27,6 +27,8 @@ Improve your sites SEO by identifying and fixing link issues in your Nuxt v3 app
27
27
  </table>
28
28
  </p>
29
29
 
30
+ ℹ️ Looking for a complete SEO solution? Check out [nuxt-seo-kit](https://github.com/harlan-zw/nuxt-seo-kit).
31
+
30
32
  ## Features
31
33
 
32
34
  - ✅ Discover broken links - 404s and internal redirects
@@ -102,7 +104,7 @@ If set to `true`, the build will fail if any broken links are found.
102
104
  ### `host`
103
105
 
104
106
  - Type: `string`
105
- - Default: `runtimeConfig.public.siteUrl`
107
+ - Default: `runtimeConfig.public.siteUrl || localhost`
106
108
  - Required: `false`
107
109
 
108
110
  The host of your site. This is required to validate absolute URLs which may be internal.
package/dist/module.d.ts CHANGED
@@ -10,7 +10,7 @@ interface ModuleOptions {
10
10
  /**
11
11
  * Your site hostname. Used to determine if absolute links are internal.
12
12
  */
13
- host?: string;
13
+ host: string;
14
14
  /**
15
15
  * Whether the build should fail when a 404 is encountered.
16
16
  */
package/dist/module.json CHANGED
@@ -5,5 +5,5 @@
5
5
  "bridge": false
6
6
  },
7
7
  "configKey": "linkChecker",
8
- "version": "0.1.6"
8
+ "version": "0.2.0"
9
9
  }
package/dist/module.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { defineNuxtModule } from '@nuxt/kit';
2
2
  import chalk from 'chalk';
3
- import { isRelative, parseURL } from 'ufo';
3
+ import { parseURL, hasProtocol } from 'ufo';
4
4
  import { load } from 'cheerio';
5
5
 
6
6
  const linkMap = {};
@@ -11,36 +11,25 @@ function getExtension(path) {
11
11
  }
12
12
  function extractLinks(html, from, { host, trailingSlash }) {
13
13
  const links = [];
14
- const _links = [];
14
+ const hostname = parseURL(host).host;
15
15
  const $ = load(html);
16
16
  $("[href]").each((i, el) => {
17
17
  const href = $(el).attr("href");
18
18
  if (!href)
19
19
  return;
20
- if (host && !isRelative(href) && href.startsWith(host))
20
+ const url = parseURL(href);
21
+ if (hasProtocol(href) && !href.startsWith("/") && url.host !== hostname)
21
22
  return;
22
23
  if (!allowedExtensions.has(getExtension(href)))
23
24
  return;
24
- _links.push({
25
- href,
26
- badTrailingSlash: href !== "/" && (trailingSlash && !href.endsWith("/") || !trailingSlash && href.endsWith("/")),
25
+ links.push({
26
+ pathname: url.pathname || "/",
27
+ url,
28
+ badAbsolute: Boolean(hostname) && hostname === url.host,
29
+ badTrailingSlash: url.pathname !== "/" && (trailingSlash && !url.pathname.endsWith("/") || !trailingSlash && url.pathname.endsWith("/")),
27
30
  element: $.html(el) || ""
28
31
  });
29
32
  });
30
- for (const link of _links.filter(Boolean)) {
31
- const parsed = parseURL(link.href);
32
- if (parsed.protocol)
33
- continue;
34
- let { pathname } = parsed;
35
- if (!pathname.startsWith("/")) {
36
- const fromURL = new URL(from, "http://localhost");
37
- pathname = new URL(pathname, fromURL).pathname;
38
- }
39
- links.push({
40
- ...link,
41
- href: pathname
42
- });
43
- }
44
33
  return links;
45
34
  }
46
35
 
@@ -56,7 +45,7 @@ const module = defineNuxtModule({
56
45
  },
57
46
  defaults(nuxt) {
58
47
  return {
59
- host: nuxt.options.runtimeConfig.public?.siteUrl,
48
+ host: nuxt.options.runtimeConfig.public?.siteUrl || "localhost",
60
49
  trailingSlash: nuxt.options.runtimeConfig.public?.trailingSlash || false,
61
50
  failOn404: true
62
51
  };
@@ -76,14 +65,14 @@ const module = defineNuxtModule({
76
65
  const links = Object.entries(linkMap);
77
66
  if (!links.length)
78
67
  return;
79
- nitro.logger.info("Scanning routes for broken links...");
68
+ nitro.logger.info(`Scanning routes for broken links... ${chalk.gray(`trailingSlashes: ${config.trailingSlash ? "`true`" : "`false`"}`)}`);
80
69
  let routeCount = 0;
81
70
  let badLinkCount = 0;
82
71
  links.forEach(([route, routes]) => {
83
72
  const brokenLinks = routes.map((r) => {
84
73
  return {
85
74
  ...r,
86
- statusCode: invalidRoutes[r.href] || 200
75
+ statusCode: invalidRoutes[r.pathname] || 200
87
76
  };
88
77
  }).filter((r) => r.statusCode !== 200 || r.badTrailingSlash);
89
78
  if (brokenLinks.length) {
@@ -97,9 +86,13 @@ const module = defineNuxtModule({
97
86
  nitro.logger.log(chalk.red(
98
87
  ` ${link.statusCode} ${link.statusCode === 404 ? "Not Found" : "Redirect"}`
99
88
  ));
89
+ } else if (link.badAbsolute) {
90
+ nitro.logger.log(chalk.yellow(
91
+ " Absolute link, should be relative"
92
+ ));
100
93
  } else if (link.badTrailingSlash) {
101
94
  nitro.logger.log(chalk.yellow(
102
- ` ${config.trailingSlash ? "Missing" : "Has added"} trailing slash`
95
+ " Incorrect trailing slash"
103
96
  ));
104
97
  }
105
98
  nitro.logger.log(` ${chalk.gray(link.element)}`);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nuxt-link-checker",
3
3
  "type": "module",
4
- "version": "0.1.6",
4
+ "version": "0.2.0",
5
5
  "packageManager": "pnpm@7.18.0",
6
6
  "license": "MIT",
7
7
  "funding": "https://github.com/sponsors/harlan-zw",
@@ -38,11 +38,11 @@
38
38
  "@nuxt/test-utils": "3.0.0",
39
39
  "@nuxtjs/eslint-config-typescript": "^12.0.0",
40
40
  "bumpp": "^8.2.1",
41
- "eslint": "8.30.0",
41
+ "eslint": "8.31.0",
42
42
  "execa": "^6.1.0",
43
43
  "nuxt": "^3.0.0",
44
44
  "pathe": "^1.0.0",
45
- "vitest": "^0.25.8"
45
+ "vitest": "^0.26.3"
46
46
  },
47
47
  "scripts": {
48
48
  "lint": "eslint \"**/*.{ts,vue,json,yml}\" --fix",