Skip to content

handbook: Install a CMS - Nuxt Studio#5122

Merged
ZJvandeWeg merged 12 commits into
mainfrom
zj-nuxt-studio
Jun 3, 2026
Merged

handbook: Install a CMS - Nuxt Studio#5122
ZJvandeWeg merged 12 commits into
mainfrom
zj-nuxt-studio

Conversation

@ZJvandeWeg
Copy link
Copy Markdown
Member

Description

To make handbook updates easier, this PR installs a CMS on the website.

@ZJvandeWeg ZJvandeWeg requested review from a team and Yndira-E as code owners June 2, 2026 22:03
@netlify
Copy link
Copy Markdown

netlify Bot commented Jun 2, 2026

Deploy Preview for flowforge-website ready!

Name Link
🔨 Latest commit 8782834
🔍 Latest deploy log https://app.netlify.com/projects/flowforge-website/deploys/6a2091f808e8eb000868051a
😎 Deploy Preview https://deploy-preview-5122--flowforge-website.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 63 (🔴 down 14 from production)
Accessibility: 96 (no change from production)
Best Practices: 100 (no change from production)
SEO: 91 (no change from production)
PWA: -
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify project configuration.

@ZJvandeWeg
Copy link
Copy Markdown
Member Author

Pending @ppawlowski configuring the env vars I supplied. But afterwards the CMS should be operational

@ZJvandeWeg
Copy link
Copy Markdown
Member Author

Env vars have been deployed, fixing CI as we speak.

@Yndira-E
Copy link
Copy Markdown
Contributor

Yndira-E commented Jun 3, 2026

@ZJvandeWeg I'm signing off now, but here are the Netlify logs:

7:35:14 PM: [11ty] Wrote 7092 search records to nuxt/public/search-index.json
7:35:14 PM: [11ty] Benchmark   5822ms  20%     1× (Data) `./src/_data/integrations.js`
7:35:14 PM: [11ty] Copied 2491 Wrote 916 files in 28.76 seconds (31.4ms each, v3.1.2)
7:35:15 PM: > flowfuse-website@1.0.0 prod:nuxt
7:35:15 PM: > npm run build --workspace=nuxt
7:35:15 PM: > flowfuse-website-nuxt@0.0.0 build
7:35:15 PM: > nuxt build
7:35:15 PM: ┌  Building Nuxt for production...
7:35:16 PM: │
7:35:16 PM: ●  Nuxt 4.4.6 (with Nitro 2.13.4, Vite 7.3.3 and Vue 3.5.34)
7:35:17 PM: [info] [nuxt-studio] Using repository: github:flowforge/website#pull/5122/head
7:35:17 PM: [warn] [@nuxtjs/mdc] removing unsafe attribute: onClick="ffCopyHex('{{ color.hex }}', this)"
7:35:19 PM: [success] [@nuxt/content] Processed 3 collections and 169 files in 2386.38ms (0 cached, 169 parsed)
7:35:20 PM: [warn] Runtime config option `studio.markdown.remarkPlugins.handbook-links.instance` may not be able to be serialized.
7:35:20 PM: │
7:35:20 PM: ●  Nitro preset: netlify
7:35:21 PM: [info] Building client...
7:35:21 PM: [info] vite v7.3.3 building client environment for production...
7:35:25 PM: [success] Components metas parsed in 3742.91ms
7:35:25 PM: [warn] [plugin nuxt:module-preload-polyfill] Sourcemap is likely to be incorrect: a plugin (nuxt:module-preload-polyfill) was used to transform files, but didn't generate a sourcemap for the transformation. Consult the plugin documentation for help
[info] transforming...
7:35:26 PM: [info] ✓ 116 modules transformed.
7:35:26 PM: │  557: storage.setItem('public-assets/img/Release-2-25-u36NE9aLQ6-560.webp', {"id":"public-assets/img/Release-2-25-u36NE9aLQ...
│  558: storage.setItem('public-assets/img/Release-2-25.png', {"id":"public-assets/img/Release-2-25.png","extension":"png","s...
│  559: storage.setItem('public-assets/img/Rethinking-Edge-AI's-Core-Orchestration-diagram-8pR9DSWavv-1300.avif', {"id":"publ...
│                                                             ^
7:35:26 PM: [error] ✗ Build failed in 5.11s
7:35:26 PM: │
7:35:26 PM: ■  Nuxt build error: RollupError: virtual:nuxt:%2Fopt%2Fbuild%2Frepo%2Fnuxt%2F.nuxt%2Fstudio-assets.mjs (559:54): Expected ',', got 'ident' (Note that you need plugins to import files that are not JavaScript)
7:35:26 PM: │  file: virtual:nuxt:%2Fopt%2Fbuild%2Frepo%2Fnuxt%2F.nuxt%2Fstudio-assets.mjs:559:54
7:35:26 PM: │  
7:35:26 PM: │  560: storage.setItem('public-assets/img/Rethinking-Edge-AI's-Core-Orchestration-diagram-8pR9DSWavv-1300.jpeg', {"id":"publ...
│  561: storage.setItem('public-assets/img/Rethinking-Edge-AI's-Core-Orchestration-diagram-8pR9DSWavv-1300.webp', {"id":"publ...
│  
7:35:26 PM: npm error Lifecycle script `build` failed with error:
7:35:26 PM: npm error code 1
7:35:26 PM: npm error path /opt/build/repo/nuxt
7:35:26 PM: npm error workspace flowfuse-website-nuxt@0.0.0
7:35:26 PM: npm error location /opt/build/repo/nuxt
7:35:26 PM: npm error command failed
7:35:26 PM: npm error command sh -c nuxt build
7:35:26 PM: ERROR: "prod:nuxt" exited with 1.
7:35:29 PM: Failed during stage 'building site': Build script returned non-zero exit code: 2 (https://ntl.fyi/exit-code-2)
7:35:29 PM: ​
7:35:29 PM: "build.command" failed                                        
7:35:29 PM: ────────────────────────────────────────────────────────────────
7:35:29 PM: ​
7:35:29 PM:   Error message
7:35:29 PM:   Command failed with exit code 1: npm run build:nuxt (https://ntl.fyi/exit-code-1)
7:35:29 PM: ​
7:35:29 PM:   Error location
7:35:29 PM:   In build.command from netlify.toml:
7:35:29 PM:   npm run build:nuxt
7:35:29 PM: ​
7:35:29 PM:   Resolved config
7:35:29 PM:   build:
7:35:29 PM:     command: npm run build:nuxt
7:35:29 PM:     commandOrigin: config
7:35:29 PM:     environment:
7:35:29 PM:       - ALGOLIA_ADMIN_KEY
7:35:29 PM:       - ALGOLIA_APP_ID
7:35:29 PM:       - ALGOLIA_INDEX_NAME
7:35:29 PM:       - ENVIRONMENT
7:35:29 PM:       - POSTHOG_APIKEY
7:35:29 PM:       - REVIEW_ID
7:35:29 PM:       - STUDIO_GITHUB_CLIENT_ID
7:35:29 PM:       - STUDIO_GITHUB_CLIENT_SECRET
7:35:29 PM:       - USER_AGENT_BLOCKER_ANALYTICS
7:35:29 PM:     publish: /opt/build/repo/nuxt/.output/public
7:35:29 PM:     publishOrigin: config
7:35:29 PM:   functions:
7:35:29 PM:     "*":
7:35:29 PM:       included_files:
7:35:29 PM:         - nuxt/.output/**
  functionsDirectory: /opt/build/repo/nuxt/.netlify/functions-internal
  headers:
    - for: /*
      values:
        Content-Security-Policy: frame-ancestors 'self';
        X-Frame-Options: SAMEORIGIN
  headersOrigin: config
  plugins:
    - inputs: {}
      origin: ui
      package: "@netlify/plugin-lighthouse"
    - inputs: {}
      origin: config
      package: netlify-plugin-cache
  redirects:
    - force: true
      from: http://flowforge.com/*
      status: 301
      to: http://flowfuse.com/:splat
    - force: true
      from: https://flowforge.com/*
      status: 301
      to: https://flowfuse.com/:splat
    - force: true
      from: http://www.flowforge.com/*
      status: 301
      to: http://flowfuse.com/:splat
    - force: true
      from: https://www.flowforge.com/*
      status: 301
      to: https://flowfuse.com/:splat
    - force: true
      from: http://flowfuze.com/*
      status: 301
      to: http://flowfuse.com/:splat
    - force: true
      from: https://flowfuze.com/*
      status: 301
      to: https://flowfuse.com/:splat
    - force: true
      from: http://www.flowfuze.com/*
      status: 301
      to: http://flowfuse.com/:splat
    - force: true
      from: https://www.flowfuze.com/*
      status: 301
      to: https://flowfuse.com/:splat
    - force: true
      from: https://flowfuse.io/*
      status: 301
      to: https://flowfuse.com/:splat
  redirectsOrigin: config
7:35:29 PM: Build failed due to a user error: Build script returned non-zero exit code: 2
7:35:29 PM: Failing build: Failed to build site
7:35:30 PM: Finished processing build request in 1m37.203s

And Netlify Analysis:

Diagnosis

Nuxt’s build fails because the generated module nuxt/.nuxt/studio-assets.mjs contains invalid JavaScript. The asset key that Nuxt is trying to write is 'public-assets/img/Rethinking-Edge-AI's-Core-Orchestration-diagram-8pR9DSWavv-1300.jpeg', but the apostrophe in AI's terminates the single-quoted string and breaks the module, producing the Rollup error shown at line 1217-line 1220.

Solution

Rename the offending asset so it no longer contains an apostrophe (for example, Rethinking-Edge-AIs-Core-Orchestration-diagram-8pR9DSWavv-1300.jpeg) and update every reference to the file (markdown content, templates, etc.) to use the new name. Commit the renamed file and reference changes, then rebuild. Nuxt will regenerate studio-assets.mjs without the syntax error, allowing the build to complete successfully.

@ZJvandeWeg
Copy link
Copy Markdown
Member Author

The file was renamed, but Netlify cached it. Now forcing the cache to be cleaned.

ZJvandeWeg and others added 11 commits June 3, 2026 12:26
Switch nitro preset from static to netlify (required for Studio's SSR
auth routes), add studio.repository config, update build scripts to use
nuxt build, and add Netlify functions directory config.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
nuxt-studio generates single-quoted JS string literals for asset keys;
apostrophes in filenames produce a syntax error at build time.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add Vite alias so @nuxt/content's generated mdc-imports.mjs can
  resolve the 'handbook-links' remark plugin key during bundling
- Remove node:path/posix from remark-handbook-links (not available in
  browser bundle); replace with inline POSIX dirname/resolve helpers
- Rename blog images with apostrophes in filenames; nuxt-studio scans
  all of nuxt/public/ and generates unescaped JS string literals that
  break the Vite bundle when filenames contain apostrophes
- Add Vite alias so @nuxt/content's generated mdc-imports.mjs can
  resolve the 'handbook-links' remark plugin key during bundling
- Remove node:path/posix from remark-handbook-links (not available in
  browser bundle); replace with inline POSIX dirname/resolve helpers
- Rename blog images with apostrophes in filenames; nuxt-studio scans
  all of nuxt/public/ and generates unescaped JS string literals that
  break the Vite bundle when filenames contain apostrophes
nuxt build with preset: 'netlify' (required for Studio OAuth) produces
a different output than nuxt generate with preset: 'static', breaking
the hyperlink check. Override NITRO_PRESET=static in CI only so the
link checker gets a full static .output/public/.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Wrap "Edit this page" links in <ClientOnly> so the /_studio href is
  not included in pre-rendered HTML (nuxt-studio injects this SSR-only
  route as an edit link on every handbook page)
- Update hyperlink path from .output/public/ to dist/ — the Netlify
  preset outputs static files to nuxt/dist/, not nuxt/.output/public/
- Revert unnecessary NITRO_PRESET=static override from previous commit
nuxt/dist was committed as a symlink to an absolute path on Yndira's
machine (/Users/yndira/.../nuxt/.output/public), breaking all Netlify
builds. nuxt/dist is already covered by nuxt/.gitignore.
nuxt-studio scans nuxt/public/ and emits unescaped JS string literals
for every file it finds. Renamed source images leave apostrophe-named
processed files in the Netlify image cache (nuxt/public/img/), which
breaks the Vite bundle. Purge them as part of clean:nuxt.
The netlify Nitro preset outputs to nuxt/dist/ (copying nuxt/public +
adding _nuxt client bundles), not nuxt/.output/public as previously
configured. Update publish dir and add a catch-all redirect so
non-static requests (/_studio/*, /_content/*, etc.) hit the SSR
function.
@ZJvandeWeg ZJvandeWeg merged commit c7952db into main Jun 3, 2026
7 checks passed
@ZJvandeWeg ZJvandeWeg deleted the zj-nuxt-studio branch June 3, 2026 20:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants