diff --git a/src/steps/render.js b/src/steps/render.js
index 2532f589..4a612b79 100644
--- a/src/steps/render.js
+++ b/src/steps/render.js
@@ -17,6 +17,14 @@ import rehypeParse from 'rehype-parse';
import { cleanupHeaderValue } from '@adobe/helix-shared-utils';
import { contentSecurityPolicyOnAST } from './csp.js';
+const LANG_REGEX = /^[a-z]{2}(?:[-_][a-z]{2})?$/i;
+
+function formatLang(lang) {
+ return lang
+ .replace('_', '-')
+ .toLowerCase();
+}
+
function appendElement($parent, $el) {
if ($el) {
$parent.children.push($el);
@@ -76,8 +84,19 @@ export default async function render(state, req, res) {
continue;
}
if (name.toLowerCase() === 'html-lang') {
- if (/^[a-z]{2}([-_]{1}[a-z]{2})?$/i.test(value)) {
- htmlLang = value;
+ if (LANG_REGEX.test(value)) {
+ htmlLang = formatLang(value);
+ }
+ // eslint-disable-next-line no-continue
+ continue;
+ }
+ if (name.toLowerCase().startsWith('hreflang-')) {
+ const lang = name.substring(9);
+ if (LANG_REGEX.test(lang)) {
+ appendElement(
+ $head,
+ createElement('link', 'rel', 'alternate', 'hreflang', formatLang(lang), 'href', value),
+ );
}
// eslint-disable-next-line no-continue
continue;
diff --git a/test/fixtures/content/page-metadata-hreflang-invalid.html b/test/fixtures/content/page-metadata-hreflang-invalid.html
new file mode 100644
index 00000000..71fe8436
--- /dev/null
+++ b/test/fixtures/content/page-metadata-hreflang-invalid.html
@@ -0,0 +1,27 @@
+
+
+ Home | Helix Project Boilerplate
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
HTML lang test
+
This is great.
+
+
+
+
+
\ No newline at end of file
diff --git a/test/fixtures/content/page-metadata-hreflang-invalid.md b/test/fixtures/content/page-metadata-hreflang-invalid.md
new file mode 100644
index 00000000..7a9744f3
--- /dev/null
+++ b/test/fixtures/content/page-metadata-hreflang-invalid.md
@@ -0,0 +1,11 @@
+# HTML lang test
+
+This is great.
+
++-------------------------------------------------------------------------------------------+
+| Metadata |
++================+==========================================================================+
+| title | Home \| Helix Project Boilerplate |
++----------------+--------------------------------------------------------------------------|
+| hreflang-x | https://helix-pages.com/x/page-metadata-hreflang |
++----------------+--------------------------------------------------------------------------+
diff --git a/test/fixtures/content/page-metadata-hreflang.html b/test/fixtures/content/page-metadata-hreflang.html
new file mode 100644
index 00000000..90afa22d
--- /dev/null
+++ b/test/fixtures/content/page-metadata-hreflang.html
@@ -0,0 +1,29 @@
+
+
+ Home | Helix Project Boilerplate
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
HTML lang test
+
This is great.
+
+
+
+
+
\ No newline at end of file
diff --git a/test/fixtures/content/page-metadata-hreflang.md b/test/fixtures/content/page-metadata-hreflang.md
new file mode 100644
index 00000000..801e59be
--- /dev/null
+++ b/test/fixtures/content/page-metadata-hreflang.md
@@ -0,0 +1,13 @@
+# HTML lang test
+
+This is great.
+
++-------------------------------------------------------------------------------------------+
+| Metadata |
++================+==========================================================================+
+| title | Home \| Helix Project Boilerplate |
++----------------+--------------------------------------------------------------------------|
+| hreflang-de | |
++----------------+--------------------------------------------------------------------------+
+| hreflang-fr-FR | |
++----------------+--------------------------------------------------------------------------+
diff --git a/test/fixtures/content/page-metadata-htmllang.html b/test/fixtures/content/page-metadata-htmllang.html
index ed3841fe..74074db8 100644
--- a/test/fixtures/content/page-metadata-htmllang.html
+++ b/test/fixtures/content/page-metadata-htmllang.html
@@ -1,4 +1,4 @@
-
+
Home | Helix Project Boilerplate
diff --git a/test/rendering.test.js b/test/rendering.test.js
index c2136020..a998d814 100644
--- a/test/rendering.test.js
+++ b/test/rendering.test.js
@@ -535,6 +535,16 @@ describe('Rendering', () => {
config = DEFAULT_CONFIG_EMPTY;
await testRender('page-metadata-htmllang-invalid', ':scope');
});
+
+ it('injects hreflang link', async () => {
+ config = DEFAULT_CONFIG_EMPTY;
+ await testRender('page-metadata-hreflang', ':scope');
+ });
+
+ it('rejects invalid hreflang', async () => {
+ config = DEFAULT_CONFIG_EMPTY;
+ await testRender('page-metadata-hreflang-invalid', ':scope');
+ });
});
describe('Miscellaneous', () => {