@flyewi/eleventy-plugin-redirects 0.1.0 → 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
@@ -40,6 +40,8 @@ By default this writes an `_redirects` file into your output directory after eve
40
40
  | `apache` | `false` | Write an Apache `.htaccess` with `Redirect` directives. |
41
41
  | `apacheFile` | `".htaccess"` | Filename for the Apache output. |
42
42
  | `html` | `false` | Also write a static HTML fallback page at each `from` URL (meta-refresh + `rel=canonical`), for hosts (e.g. GitHub Pages) that can't act on `_redirects`/`.htaccess`. |
43
+ | `htmlLang` | `"en"` | `lang` attribute of the HTML fallback pages. |
44
+ | `htmlMessage` | `"This page has moved to"` | Text shown (followed by the link) on the HTML fallback pages, for the moment before the redirect or when it doesn't fire. |
43
45
  | `log` | `true` | Log a one-line summary after each build. |
44
46
 
45
47
  ## Netlify output
@@ -65,8 +67,11 @@ With `html: true`, each `from` path also gets a real HTML file at that URL (e.g.
65
67
  ```html
66
68
  <meta http-equiv="refresh" content="0; url=/new-path/">
67
69
  <link rel="canonical" href="/new-path/">
70
+ <script>location.replace("/new-path/" + location.hash);</script>
68
71
  ```
69
72
 
73
+ The script redirects immediately and keeps the URL fragment (`/old-path/#section` → `/new-path/#section`), like a server-side redirect would; the meta refresh is the fallback when JavaScript is off. If the target already contains a `#fragment`, that one is kept instead.
74
+
70
75
  This is a static fallback for platforms without server-side redirect support — a real `_redirects`/`.htaccess` (or your host/CDN's redirect rules) is always the better option when available, since the HTML approach is a moment slower and depends on the browser executing the refresh.
71
76
 
72
77
  ## License
package/lib/formats.js CHANGED
@@ -16,21 +16,32 @@ function escapeAttr(str) {
16
16
  .replace(/>/g, "&gt;");
17
17
  }
18
18
 
19
+ // JSON.stringify yields a valid JS string literal; escaping "<" additionally
20
+ // keeps a target containing "</script>" from closing the inline script early.
21
+ function toScriptString(str) {
22
+ return JSON.stringify(String(str)).replace(/</g, "\\u003c");
23
+ }
24
+
19
25
  // A static fallback for hosts that can't act on _redirects/.htaccess (e.g.
20
26
  // GitHub Pages): an actual HTML file at the old URL that both redirects
21
27
  // browsers instantly and points crawlers at the new canonical URL.
22
- function toHtmlPage(to) {
28
+ // The script runs before the meta refresh fires and carries the URL fragment
29
+ // (#section) over, as a server-side 301 would; the meta refresh remains as the
30
+ // no-JS fallback. A target that already has its own fragment keeps it.
31
+ function toHtmlPage(to, { lang = "en", message = "This page has moved to" } = {}) {
23
32
  const target = escapeAttr(to);
33
+ const hash = String(to).includes("#") ? "" : " + location.hash";
24
34
  return `<!doctype html>
25
- <html lang="en">
35
+ <html lang="${escapeAttr(lang)}">
26
36
  <head>
27
37
  <meta charset="utf-8">
28
- <title>Redirecting…</title>
38
+ <title>${escapeAttr(message)} ${target}</title>
29
39
  <meta http-equiv="refresh" content="0; url=${target}">
30
40
  <link rel="canonical" href="${target}">
41
+ <script>location.replace(${toScriptString(to)}${hash});</script>
31
42
  </head>
32
43
  <body>
33
- <p>This page has moved to <a href="${target}">${target}</a>.</p>
44
+ <p>${escapeAttr(message)} <a href="${target}">${target}</a>.</p>
34
45
  </body>
35
46
  </html>
36
47
  `;
package/lib/redirects.js CHANGED
@@ -10,6 +10,8 @@ const DEFAULTS = {
10
10
  netlify: true,
11
11
  apache: false,
12
12
  html: false,
13
+ htmlLang: "en",
14
+ htmlMessage: "This page has moved to",
13
15
  netlifyFile: "_redirects",
14
16
  apacheFile: ".htaccess",
15
17
  log: true,
@@ -59,7 +61,10 @@ module.exports = function redirectsPlugin(eleventyConfig, userOptions = {}) {
59
61
  for (const { from, to } of list) {
60
62
  const outPath = path.join(outputDir, toOutputPath(from));
61
63
  fs.mkdirSync(path.dirname(outPath), { recursive: true });
62
- fs.writeFileSync(outPath, toHtmlPage(to));
64
+ fs.writeFileSync(
65
+ outPath,
66
+ toHtmlPage(to, { lang: options.htmlLang, message: options.htmlMessage })
67
+ );
63
68
  }
64
69
  }
65
70
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flyewi/eleventy-plugin-redirects",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Eleventy plugin that generates Netlify _redirects, Apache .htaccess, and static HTML fallback pages from a single redirects config.",
5
5
  "main": "lib/redirects.js",
6
6
  "type": "commonjs",