Skip to content

Commit c001546

Browse files
committed
build: fix deploy to github pages
1 parent 8b9b802 commit c001546

2 files changed

Lines changed: 30 additions & 16 deletions

File tree

.github/workflows/deploy-stories.yml

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,22 @@ jobs:
4545
run: pnpm install
4646

4747
# ── Frame pass ──────────────────────────────────────────────────────────
48-
# Generates the component renderer routes at /-frame/**
48+
# Generates the bare component renderer.
4949
# NUXT_STORIES_MODE overrides the mode option so the same nuxt.config is reused.
50+
#
51+
# The frame is built with a base URL that is a *sibling* of the shell's base
52+
# (/nuxt-stories/nuxt-stories-frame/ vs /nuxt-stories/). This gives the frame:
53+
# • its own _nuxt/ bundle — no asset collision with the shell
54+
# • a URL namespace distinct from the shell's /:story* catch-all routes,
55+
# so the shell's 200.html SPA fallback can never be served for frame paths
5056

5157
- name: Generate frame output
5258
working-directory: playground
5359
run: pnpm nuxi generate
5460
env:
5561
NUXT_STORIES: "1"
5662
NUXT_STORIES_MODE: frame
57-
# Frame gets its own sub-base so its _nuxt/ assets land under /-frame/_nuxt/
58-
# after the merge, preventing collision with the shell's _nuxt/ bundle.
59-
NUXT_APP_BASE_URL: /nuxt-stories/-frame/
63+
NUXT_APP_BASE_URL: /nuxt-stories/nuxt-stories-frame/
6064

6165
- name: Save frame output
6266
run: mkdir -p playground/.output-tmp && mv playground/.output/public playground/.output-tmp/frame-public
@@ -71,15 +75,16 @@ jobs:
7175
NUXT_STORIES: "1"
7276
NUXT_STORIES_MODE: shell
7377
NUXT_APP_BASE_URL: /nuxt-stories/
74-
78+
# Tell the shell where the frame is served from so iframe srcs are correct.
79+
NUXT_STORIES_FRAME_BASE_PATH: /nuxt-stories-frame
7580
# ── Merge outputs ───────────────────────────────────────────────────────
76-
# Copy the frame output's /-frame/** into the shell output so both are
77-
# served from the same origin (required for same-origin postMessage).
81+
# Copy the frame output into nuxt-stories-frame/ inside the shell output so both
82+
# are served from the same origin (required for same-origin postMessage).
7883

7984
- name: Merge frame output into shell output
8085
run: |
81-
mkdir -p playground/.output/public/-frame
82-
cp -r playground/.output-tmp/frame-public/. playground/.output/public/-frame/
86+
mkdir -p playground/.output/public/nuxt-stories-frame
87+
cp -r playground/.output-tmp/frame-public/. playground/.output/public/nuxt-stories-frame/
8388
rm -rf playground/.output-tmp
8489
8590
# GitHub Pages ignores folders prefixed with _ by default; .nojekyll disables this.

src/module.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,22 @@ export default defineNuxtModule<NuxtStoriesOptions>({
9595
nuxt.options.pages = true
9696

9797
const routeBasePath = joinURL('/', options.route?.path || '')
98-
const frameBasePath = routeBasePath === '/' ? '/-frame' : routeBasePath + '-frame'
98+
// NUXT_STORIES_FRAME_BASE_PATH lets the CI build override where the frame lives.
99+
// In the two-pass GitHub Actions workflow the shell is built with e.g.
100+
// NUXT_STORIES_FRAME_BASE_PATH=/nuxt-stories-frame
101+
// so its iframes point to /nuxt-stories/nuxt-stories-frame/…, while the frame is
102+
// built with NUXT_APP_BASE_URL=/nuxt-stories/nuxt-stories-frame/ and its output is
103+
// merged into the artifact under nuxt-stories-frame/. This gives the frame its own
104+
// _nuxt/ bundle (no asset collision) and a dedicated URL namespace that is clearly
105+
// distinct from the shell's /:story* catch-all routes.
106+
const frameBasePath = process.env.NUXT_STORIES_FRAME_BASE_PATH
107+
|| (routeBasePath === '/' ? '/-frame' : routeBasePath + '-frame')
99108

100109
// In a two-pass static build (GitHub Actions) the frame is generated with
101-
// NUXT_APP_BASE_URL=/base/-frame/ so the iframe-facing /-frame/* path is already
102-
// encoded in the base URL. Routes must therefore live at / (not /-frame/*) so
103-
// that the generated files don't get an extra /-frame/ prefix that would make
104-
// them double-nested after the merge step.
110+
// NUXT_APP_BASE_URL=/nuxt-stories/<frame-base>/ so that base path is already
111+
// encoded in the app base URL. Routes must therefore live at / (not at the
112+
// frame base path) so that the generated files land directly in .output/public/
113+
// and do not get double-prefixed after the merge step.
105114
const staticFrameMode = mode === 'frame' && !nuxt.options.dev
106115
const effectiveFrameBasePath = staticFrameMode ? '/' : frameBasePath
107116

@@ -131,9 +140,9 @@ export default defineNuxtModule<NuxtStoriesOptions>({
131140
// Disable link-crawling for both frame and shell static builds.
132141
// Frame: avoids a 404 on '/' when no root page exists.
133142
// Shell: StoriesPage is SSR'd with <iframe :src="iframeSrc">, whose computed value
134-
// contains /-frame/... URLs. If crawlLinks is true, Nitro follows those links and
143+
// contains frame URLs. If crawlLinks is true, Nitro follows those links and
135144
// renders them with the shell router (/:story* catches everything), writing shell
136-
// HTML into the /-frame/ subtree and clobbering the real frame output after merge.
145+
// HTML into the frame subtree and clobbering the real frame output after merge.
137146
// Explicit prerender routes (storyPaths) cover all required pages for both modes.
138147
if (mode === 'frame' || (mode === 'shell' && !nuxt.options.dev)) {
139148
nuxt.options.nitro.prerender ||= {}

0 commit comments

Comments
 (0)