mnfst-render 0.5.5 → 0.5.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.
Files changed (2) hide show
  1. package/manifest.render.mjs +33 -10
  2. package/package.json +1 -1
@@ -1356,7 +1356,7 @@ function generateLocaleVariantHtml({
1356
1356
  html = stripEmptyInlineMaskStyles(html);
1357
1357
  html = stripResolvedXIconDirectives(html);
1358
1358
  // markPrerenderedManifestComponents must run BEFORE stripPrerenderHydrateMarkers so it can
1359
- // detect data-prerender-hydrate markers and skip components inside hydrate islands.
1359
+ // detect data-hydrate markers and skip components inside hydrate islands.
1360
1360
  html = markPrerenderedManifestComponents(html);
1361
1361
 
1362
1362
  const fileSegments = pathToFileSegments(pathSeg ? '/' + pathSeg : '/');
@@ -2239,13 +2239,36 @@ async function runPrerender(config) {
2239
2239
  });
2240
2240
 
2241
2241
  // Strip x-markdown from elements that already have baked content.
2242
- // The markdown plugin hides elements with opacity:0 on init, then re-fetches and re-renders.
2243
- // For prerendered pages the content is already baked — removing x-markdown prevents the
2244
- // runtime plugin from re-processing (and temporarily hiding) the static content.
2242
+ // The markdown plugin hides elements with opacity:0 on init, then re-fetches
2243
+ // and re-renders. For prerendered pages the content is already baked —
2244
+ // removing x-markdown prevents the runtime plugin from re-processing (and
2245
+ // temporarily hiding) the static content.
2246
+ //
2247
+ // We ALSO clear any leftover `opacity: 0` inline style the plugin set
2248
+ // before/while rendering. On dynamic expressions that initially evaluate
2249
+ // empty (e.g. article content keyed off `$route` before `$x.articles` has
2250
+ // loaded), the plugin sets opacity to 0 and may never restore it to 1 if
2251
+ // the effect re-fires with an empty value. The end state in the
2252
+ // serialized HTML has rendered content but opacity:0 — invisible in
2253
+ // production. Since we're also removing x-markdown (so the runtime
2254
+ // plugin doesn't re-hide the element), leaving the inline style would
2255
+ // permanently hide authored content.
2245
2256
  await page.evaluate(() => {
2246
2257
  document.querySelectorAll('[x-markdown]').forEach((el) => {
2247
2258
  if (!el.textContent.trim() && !el.innerHTML.trim()) return;
2248
2259
  el.removeAttribute('x-markdown');
2260
+ // Clean up opacity-0 + transition inline styles the plugin left behind.
2261
+ const style = el.getAttribute('style') || '';
2262
+ if (style) {
2263
+ const cleaned = style
2264
+ .replace(/\bopacity\s*:\s*0(?:\.\d+)?\s*;?/gi, '')
2265
+ .replace(/\btransition\s*:\s*opacity[^;]*;?/gi, '')
2266
+ .replace(/;\s*;/g, ';')
2267
+ .replace(/^\s*;\s*|\s*;\s*$/g, '')
2268
+ .trim();
2269
+ if (cleaned) el.setAttribute('style', cleaned);
2270
+ else el.removeAttribute('style');
2271
+ }
2249
2272
  });
2250
2273
  });
2251
2274
 
@@ -2404,7 +2427,7 @@ async function runPrerender(config) {
2404
2427
  // $url, $auth, or iterates over getter names (filtered*, results, searchResults). See docs prerender + local.data.
2405
2428
  await page.evaluate(() => {
2406
2429
  document.querySelectorAll('template[x-for]').forEach((tpl) => {
2407
- if (tpl.hasAttribute('data-prerender-hydrate') || tpl.closest('[data-prerender-hydrate]')) {
2430
+ if (tpl.hasAttribute('data-hydrate') || tpl.closest('[data-hydrate]')) {
2408
2431
  tpl.removeAttribute('data-prerender-collapsed');
2409
2432
  tpl.removeAttribute('data-prerender-static-generated');
2410
2433
  return;
@@ -2485,7 +2508,7 @@ async function runPrerender(config) {
2485
2508
  await page.evaluate(() => {
2486
2509
  const loopVarRx = /^\s*(?:\(\s*([A-Za-z_$][\w$]*)(?:\s*,\s*([A-Za-z_$][\w$]*))?\s*\)|([A-Za-z_$][\w$]*))\s+in\s+/;
2487
2510
  document.querySelectorAll('template[x-for][data-prerender-static-generated="1"]').forEach((tpl) => {
2488
- if (tpl.hasAttribute('data-prerender-hydrate') || tpl.closest('[data-prerender-hydrate]')) return;
2511
+ if (tpl.hasAttribute('data-hydrate') || tpl.closest('[data-hydrate]')) return;
2489
2512
  const xFor = (tpl.getAttribute('x-for') || '').trim();
2490
2513
  const m = xFor.match(loopVarRx);
2491
2514
  const itemVar = m ? (m[1] || m[3] || '') : '';
@@ -2499,7 +2522,7 @@ async function runPrerender(config) {
2499
2522
  // Only process clones that contain data-hydrate descendants
2500
2523
  if (
2501
2524
  !n.hasAttribute('x-data') &&
2502
- (n.hasAttribute('data-prerender-hydrate') || n.querySelector('[data-prerender-hydrate]'))
2525
+ (n.hasAttribute('data-hydrate') || n.querySelector('[data-hydrate]'))
2503
2526
  ) {
2504
2527
  try {
2505
2528
  const A = window.Alpine;
@@ -2541,7 +2564,7 @@ async function runPrerender(config) {
2541
2564
  const nodes = [el, ...Array.from(el.querySelectorAll('*'))];
2542
2565
  for (const node of nodes) {
2543
2566
  // Skip elements inside data-hydrate islands — their bindings must remain live
2544
- if (node.hasAttribute('data-prerender-hydrate') || node.closest('[data-prerender-hydrate]')) continue;
2567
+ if (node.hasAttribute('data-hydrate') || node.closest('[data-hydrate]')) continue;
2545
2568
  const attrs = node.attributes ? Array.from(node.attributes) : [];
2546
2569
  for (const attr of attrs) {
2547
2570
  if (!bindingAttrRegex.test(attr.name)) continue;
@@ -2579,7 +2602,7 @@ async function runPrerender(config) {
2579
2602
  };
2580
2603
 
2581
2604
  document.querySelectorAll('template[x-for]').forEach((tpl) => {
2582
- if (tpl.hasAttribute('data-prerender-hydrate') || tpl.closest('[data-prerender-hydrate]')) return;
2605
+ if (tpl.hasAttribute('data-hydrate') || tpl.closest('[data-hydrate]')) return;
2583
2606
  const xFor = (tpl.getAttribute('x-for') || '').trim();
2584
2607
  const m = xFor.match(loopVarRegex);
2585
2608
  const itemVar = m ? (m[1] || m[3] || '') : '';
@@ -2608,7 +2631,7 @@ async function runPrerender(config) {
2608
2631
  const runBatch = typeof A?.mutateDom === 'function' ? (fn) => A.mutateDom(fn) : (fn) => fn();
2609
2632
  runBatch(() => {
2610
2633
  document.querySelectorAll('template[x-for][data-prerender-static-generated="1"]').forEach((tpl) => {
2611
- if (tpl.hasAttribute('data-prerender-hydrate') || tpl.closest('[data-prerender-hydrate]')) return;
2634
+ if (tpl.hasAttribute('data-hydrate') || tpl.closest('[data-hydrate]')) return;
2612
2635
  const parent = tpl.parentNode;
2613
2636
  if (!parent) {
2614
2637
  tpl.remove();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mnfst-render",
3
- "version": "0.5.5",
3
+ "version": "0.5.6",
4
4
  "description": "Render Manifest sites to static HTML for SEO",
5
5
  "type": "module",
6
6
  "bin": {