mnfst-render 0.3.4 → 0.3.6

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.
@@ -951,6 +951,34 @@ function stripRedundantImgSrcBindings(html) {
951
951
  });
952
952
  }
953
953
 
954
+ /**
955
+ * Manifest runtime replaces <x-*> component placeholders by fetching source .html, which wipes
956
+ * prerender-baked markup (stripped :style, expanded lists, etc.). Tag opens with data-pre-rendered
957
+ * are skipped by manifest.components.processor — required for static prerender output to hydrate correctly.
958
+ */
959
+ // Prerender inlined Iconify SVG under <i x-icon="iterator.icon">; drop x-icon so Alpine does not evaluate module/item.
960
+ function stripResolvedXIconDirectives(html) {
961
+ return html.replace(/<i\b([^>]*)>([\s\S]*?)<\/i>/gi, (full, attrs, inner) => {
962
+ if (!/\sx-icon\s*=/i.test(attrs)) return full;
963
+ if (!/<svg\b/i.test(inner) || !/\bdata-icon\s*=/i.test(inner)) return full;
964
+ const cleaned = attrs
965
+ .replace(/\s+x-icon\s*=\s*"[^"]*"/gi, '')
966
+ .replace(/\s+x-icon\s*=\s*'[^']*'/gi, '')
967
+ .trim();
968
+ const sp = cleaned ? ' ' : '';
969
+ return `<i${sp}${cleaned}>${inner}</i>`;
970
+ });
971
+ }
972
+
973
+ function markPrerenderedManifestComponents(html) {
974
+ return html.replace(/<(x-[a-z][\w-]*)([^>]*)>/gi, (full, tag, attrs) => {
975
+ const a = attrs || '';
976
+ if (/\bdata-pre-rendered\s*=/i.test(a) || /\bdata-processed\s*=/i.test(a)) return full;
977
+ const spacer = /\S/.test(a) ? ' ' : '';
978
+ return `<${tag}${a}${spacer}data-pre-rendered="1">`;
979
+ });
980
+ }
981
+
954
982
  // Remove empty inline mask-image styles emitted before data resolves
955
983
  // (e.g. style="mask-image: url()"), while keeping any :style/x-bind:style bindings.
956
984
  function stripEmptyInlineMaskStyles(html) {
@@ -1812,7 +1840,7 @@ async function runPrerender(config) {
1812
1840
  await page.evaluate(() => {
1813
1841
  const loopVarRegex = /^\s*(?:\(\s*([A-Za-z_$][\w$]*)(?:\s*,\s*([A-Za-z_$][\w$]*))?\s*\)|([A-Za-z_$][\w$]*))\s+in\s+/;
1814
1842
  // Include x-init: expanded clones still had x-init="getDescription(article)" etc.; Alpine then throws (article undefined).
1815
- const bindingAttrRegex = /^(?:x-bind:|:|x-text|x-html|x-show|x-if|x-model|x-effect|x-init|x-on:|@)/;
1843
+ const bindingAttrRegex = /^(?:x-bind:|:|x-text|x-html|x-show|x-if|x-model|x-effect|x-init|x-icon|x-on:|@)/;
1816
1844
  const hasVar = (expr, varName) => varName && new RegExp(`\\b${varName}\\b`).test(expr || '');
1817
1845
  const stripLoopBindings = (el, itemVar, indexVar) => {
1818
1846
  const nodes = [el, ...Array.from(el.querySelectorAll('*'))];
@@ -1906,7 +1934,7 @@ async function runPrerender(config) {
1906
1934
  // outside their template scope. These throw Alpine errors in live static hosting.
1907
1935
  await page.evaluate(() => {
1908
1936
  const loopVarRegex = /^\s*(?:\(\s*([A-Za-z_$][\w$]*)(?:\s*,\s*([A-Za-z_$][\w$]*))?\s*\)|([A-Za-z_$][\w$]*))\s+in\s+/;
1909
- const bindingAttrRegex = /^(?:x-bind:|:|x-text|x-html|x-show|x-if|x-model|x-effect|x-init|x-on:|@)/;
1937
+ const bindingAttrRegex = /^(?:x-bind:|:|x-text|x-html|x-show|x-if|x-model|x-effect|x-init|x-icon|x-on:|@)/;
1910
1938
  const hasVar = (expr, varName) => varName && new RegExp(`\\b${varName}\\b`).test(expr || '');
1911
1939
  const elementReferencesLoopScope = (el, itemVar, indexVar) => {
1912
1940
  if (!el) return false;
@@ -2009,6 +2037,7 @@ async function runPrerender(config) {
2009
2037
  html = stripPrerenderDynamicBindings(html);
2010
2038
  html = stripRedundantImgSrcBindings(html);
2011
2039
  html = stripEmptyInlineMaskStyles(html);
2040
+ html = stripResolvedXIconDirectives(html);
2012
2041
  html = rewriteHtmlAssetPaths(html, fileSegments.length);
2013
2042
  const liveBase = config.liveUrl.replace(/\/$/, '');
2014
2043
  const canonicalHreflang = buildCanonicalAndHreflang(is404 ? '' : pathSeg, locales, defaultLocale, liveBase);
@@ -2019,6 +2048,7 @@ async function runPrerender(config) {
2019
2048
  const routeDepth = fileSegments.length;
2020
2049
  const prerenderedMeta = `<meta name="manifest:prerendered" content="1">\n`;
2021
2050
  html = html.replace('</head>', `${canonicalHreflang}${injectOgLocale ? ogLocale : ''}${baseMeta}${prerenderedMeta}<meta name="manifest:router-base-depth" content="${routeDepth}">\n</head>`);
2051
+ html = markPrerenderedManifestComponents(html);
2022
2052
  mkdirSync(outDir, { recursive: true });
2023
2053
  writeFileSync(outFile, html, 'utf8');
2024
2054
  pushDebug({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mnfst-render",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
4
4
  "description": "Render Manifest sites to static HTML for SEO",
5
5
  "type": "module",
6
6
  "bin": {