Skip to content

Commit 461d95e

Browse files
committed
fix: SSG playground page with client-only editor loading
- Remove /playground exclusion from SSG includedRoutes - Extract PlaygroundContent as async component (client-only) - Render app bar skeleton during SSG to prevent home page flash - Add PlaygroundContent chunk to PWA globIgnores
1 parent d95b7ea commit 461d95e

File tree

4 files changed

+79
-47
lines changed

4 files changed

+79
-47
lines changed

apps/docs/src/components.d.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,14 +144,10 @@ declare module 'vue' {
144144
PlaygroundEditorBreadcrumbs: typeof import('./components/playground/editor/PlaygroundEditorBreadcrumbs.vue')['default']
145145
PlaygroundEditorFileTree: typeof import('./components/playground/editor/PlaygroundEditorFileTree.vue')['default']
146146
PlaygroundEditorPreview: typeof import('./components/playground/editor/PlaygroundEditorPreview.vue')['default']
147-
PlaygroundEditorTab: typeof import('./components/playground/editor/PlaygroundEditorTab.vue')['default']
148147
PlaygroundEditorTabs: typeof import('./components/playground/editor/PlaygroundEditorTabs.vue')['default']
149-
PlaygroundLeft: typeof import('./components/playground/PlaygroundLeft.vue')['default']
150148
PlaygroundMarkdown: typeof import('./components/playground/markdown/PlaygroundMarkdown.vue')['default']
151149
PlaygroundMarkdownFooter: typeof import('./components/playground/markdown/PlaygroundMarkdownFooter.vue')['default']
152150
PlaygroundMarkdownHeader: typeof import('./components/playground/markdown/PlaygroundMarkdownHeader.vue')['default']
153-
PlaygroundResizeBar: typeof import('./components/playground/PlaygroundResizeBar.vue')['default']
154-
PlaygroundRight: typeof import('./components/playground/PlaygroundRight.vue')['default']
155151
PlaygroundWorkspace: typeof import('./components/playground/workspace/PlaygroundWorkspace.vue')['default']
156152
PlaygroundWorkspaceBottom: typeof import('./components/playground/workspace/PlaygroundWorkspaceBottom.vue')['default']
157153
PlaygroundWorkspaceLeft: typeof import('./components/playground/workspace/PlaygroundWorkspaceLeft.vue')['default']
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<script setup lang="ts">
2+
// Content
3+
import IntroPanel from '@/skillz/intro.md'
4+
</script>
5+
6+
<template>
7+
<PlaygroundApp>
8+
<PlaygroundAppBar />
9+
10+
<PlaygroundAppContent>
11+
<PlaygroundAppLeft>
12+
<PlaygroundMarkdownHeader>
13+
Introduction
14+
</PlaygroundMarkdownHeader>
15+
16+
<PlaygroundMarkdown :component="IntroPanel" />
17+
</PlaygroundAppLeft>
18+
19+
<PlaygroundAppRight>
20+
<PlaygroundWorkspace>
21+
<PlaygroundWorkspaceTop>
22+
<PlaygroundWorkspaceLeft>
23+
<PlaygroundEditorFileTree />
24+
</PlaygroundWorkspaceLeft>
25+
26+
<PlaygroundWorkspaceRight>
27+
<PlaygroundEditorTabs />
28+
29+
<PlaygroundEditorBreadcrumbs />
30+
31+
<PlaygroundEditor />
32+
</PlaygroundWorkspaceRight>
33+
34+
<PlaygroundWorkspaceSide>
35+
<PlaygroundEditorPreview />
36+
</PlaygroundWorkspaceSide>
37+
</PlaygroundWorkspaceTop>
38+
39+
<PlaygroundWorkspaceBottom>
40+
<PlaygroundEditorPreview />
41+
</PlaygroundWorkspaceBottom>
42+
</PlaygroundWorkspace>
43+
</PlaygroundAppRight>
44+
</PlaygroundAppContent>
45+
</PlaygroundApp>
46+
</template>

apps/docs/src/pages/playground.vue

Lines changed: 31 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
<script setup lang="ts">
2+
import { IN_BROWSER } from '#v0/constants/globals'
23
import { useHead } from '@unhead/vue'
4+
import { defineAsyncComponent, shallowRef } from 'vue'
35
4-
// Content
5-
import IntroPanel from '@/skillz/intro.md'
6+
const isLoaded = shallowRef(false)
7+
8+
const PlaygroundContent = IN_BROWSER
9+
? defineAsyncComponent({
10+
loader: () => import('@/components/playground/PlaygroundContent.vue'),
11+
onError: () => {},
12+
})
13+
: undefined
614
715
definePage({
816
meta: {
@@ -22,43 +30,25 @@
2230
</script>
2331

2432
<template>
25-
<PlaygroundApp>
26-
<PlaygroundAppBar />
27-
28-
<PlaygroundAppContent>
29-
<PlaygroundAppLeft>
30-
<PlaygroundMarkdownHeader>
31-
Introduction
32-
</PlaygroundMarkdownHeader>
33-
34-
<PlaygroundMarkdown :component="IntroPanel" />
35-
</PlaygroundAppLeft>
36-
37-
<PlaygroundAppRight>
38-
<PlaygroundWorkspace>
39-
<PlaygroundWorkspaceTop>
40-
<PlaygroundWorkspaceLeft>
41-
<PlaygroundEditorFileTree />
42-
</PlaygroundWorkspaceLeft>
43-
44-
<PlaygroundWorkspaceRight>
45-
<PlaygroundEditorTabs />
46-
47-
<PlaygroundEditorBreadcrumbs />
48-
49-
<PlaygroundEditor />
50-
</PlaygroundWorkspaceRight>
51-
52-
<PlaygroundWorkspaceSide>
53-
<PlaygroundEditorPreview />
54-
</PlaygroundWorkspaceSide>
55-
</PlaygroundWorkspaceTop>
56-
57-
<PlaygroundWorkspaceBottom>
58-
<PlaygroundEditorPreview />
59-
</PlaygroundWorkspaceBottom>
60-
</PlaygroundWorkspace>
61-
</PlaygroundAppRight>
62-
</PlaygroundAppContent>
63-
</PlaygroundApp>
33+
<div class="h-screen flex flex-col bg-surface">
34+
<!-- SSG/loading skeleton: shown until async component mounts -->
35+
<template v-if="!PlaygroundContent">
36+
<header class="flex items-center justify-between h-[48px] px-3 border-b border-divider bg-surface">
37+
<div class="flex items-center gap-3">
38+
<div class="w-8 h-8" />
39+
40+
<img
41+
alt="Vuetify Play"
42+
class="h-7"
43+
src="https://vuetifyjs.b-cdn.net/docs/images/one/logos/vplay-logo-dark.svg"
44+
>
45+
</div>
46+
</header>
47+
48+
<div class="flex-1" />
49+
</template>
50+
51+
<!-- Client-only: full playground -->
52+
<component :is="PlaygroundContent" v-if="PlaygroundContent" />
53+
</div>
6454
</template>

apps/docs/vite.config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export default defineConfig({
4949
])
5050
const apiRoutes = apiSlugs.map(slug => `/api/${slug}`)
5151
const skillzRoutes = skillzSlugs.map(slug => `/skillz/${slug}`)
52-
return [...paths, ...apiRoutes, ...skillzRoutes].filter(p => p !== '/playground')
52+
return [...paths, ...apiRoutes, ...skillzRoutes]
5353
},
5454
onFinished () {
5555
generateSitemap({
@@ -104,7 +104,7 @@ export default defineConfig({
104104
// Exclude large on-demand chunks from precache
105105
// - Mermaid/Cytoscape: diagram tools, loaded only when docs use them
106106
// - vue.worker/playground/jsx: Monaco editor assets, only needed in the playground
107-
globIgnores: ['**/*Diagram-*.js', '**/mermaid*.js', '**/cytoscape*.js', '**/vue.worker*.js', '**/playground-*.js', '**/jsx-*.js'],
107+
globIgnores: ['**/*Diagram-*.js', '**/mermaid*.js', '**/cytoscape*.js', '**/vue.worker*.js', '**/playground-*.js', '**/Playground*-*.js', '**/jsx-*.js'],
108108
navigateFallback: null,
109109
},
110110
}),

0 commit comments

Comments
 (0)