prev-cli 0.16.3 → 0.16.4

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.
package/dist/cli.js CHANGED
@@ -859,6 +859,28 @@ async function createViteConfig(options) {
859
859
  });
860
860
  }
861
861
  },
862
+ {
863
+ name: "prev-spa-fallback",
864
+ configureServer(server) {
865
+ return () => {
866
+ server.middlewares.use((req, res, next) => {
867
+ const urlPath = req.url?.split("?")[0] || "";
868
+ if (urlPath.startsWith("/__") || urlPath.startsWith("/@") || urlPath.startsWith("/node_modules") || urlPath.includes(".")) {
869
+ return next();
870
+ }
871
+ const indexPath = path7.join(srcRoot2, "theme/index.html");
872
+ if (existsSync5(indexPath)) {
873
+ server.transformIndexHtml(req.url, readFileSync4(indexPath, "utf-8")).then((html) => {
874
+ res.setHeader("Content-Type", "text/html");
875
+ res.end(html);
876
+ }).catch(next);
877
+ return;
878
+ }
879
+ next();
880
+ });
881
+ };
882
+ }
883
+ },
862
884
  {
863
885
  name: "prev-preview-server",
864
886
  resolveId(id) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prev-cli",
3
- "version": "0.16.3",
3
+ "version": "0.16.4",
4
4
  "description": "Transform MDX directories into beautiful documentation websites",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -32,8 +32,8 @@ export function Preview({ src, height = 400, title, mode = 'wasm', showHeader =
32
32
 
33
33
  const iframeRef = useRef<HTMLIFrameElement>(null)
34
34
 
35
- // URL depends on mode
36
- const previewUrl = mode === 'wasm' ? '/_preview-runtime' : `/_preview/${src}`
35
+ // URL depends on mode - wasm mode needs src param
36
+ const previewUrl = mode === 'wasm' ? `/_preview-runtime?src=${src}` : `/_preview/${src}`
37
37
  const displayTitle = title || src
38
38
 
39
39
  // Calculate current width
@@ -1,5 +1,5 @@
1
1
  import React, { useState, useRef, useEffect } from 'react'
2
- import { Link } from '@tanstack/react-router'
2
+ import { Link, useLocation } from '@tanstack/react-router'
3
3
  import type { PageTree } from 'fumadocs-core/server'
4
4
  import { previews } from 'virtual:prev-previews'
5
5
  import { IconMenu2, IconLayoutGrid, IconSun, IconMoon, IconArrowsMaximize, IconArrowsMinimize } from '@tabler/icons-react'
@@ -20,6 +20,8 @@ export function Toolbar({ tree, onThemeToggle, onWidthToggle, isDark, isFullWidt
20
20
  const [dragging, setDragging] = useState(false)
21
21
  const dragStart = useRef({ x: 0, y: 0 })
22
22
  const toolbarRef = useRef<HTMLDivElement>(null)
23
+ const location = useLocation()
24
+ const isOnPreviews = location.pathname.startsWith('/previews')
23
25
 
24
26
  const handleMouseDown = (e: React.MouseEvent) => {
25
27
  if ((e.target as HTMLElement).closest('button, a')) return
@@ -63,7 +65,7 @@ export function Toolbar({ tree, onThemeToggle, onWidthToggle, isDark, isFullWidt
63
65
  </button>
64
66
 
65
67
  {previews && previews.length > 0 && (
66
- <Link to="/previews" className="toolbar-btn" title="Previews">
68
+ <Link to="/previews" className={`toolbar-btn ${isOnPreviews ? 'active' : ''}`} title="Previews">
67
69
  <IconLayoutGrid size={18} />
68
70
  </Link>
69
71
  )}
@@ -6,6 +6,8 @@ import {
6
6
  createRootRoute,
7
7
  createRoute,
8
8
  Outlet,
9
+ redirect,
10
+ Navigate,
9
11
  } from '@tanstack/react-router'
10
12
  import { MDXProvider } from '@mdx-js/react'
11
13
  import { pages, sidebar } from 'virtual:prev-pages'
@@ -257,6 +259,10 @@ const previewDetailRoute = createRoute({
257
259
  component: PreviewPage,
258
260
  })
259
261
 
262
+ // Check if we have an index page (route '/')
263
+ const hasIndexPage = pages.some((page: { route: string }) => page.route === '/')
264
+ const firstPage = pages[0] as { route: string; file: string; title?: string; description?: string; frontmatter?: Record<string, unknown> } | undefined
265
+
260
266
  // Create routes from pages
261
267
  const pageRoutes = pages.map((page: { route: string; file: string; title?: string; description?: string; frontmatter?: Record<string, unknown> }) => {
262
268
  const Component = getPageComponent(page.file)
@@ -272,9 +278,30 @@ const pageRoutes = pages.map((page: { route: string; file: string; title?: strin
272
278
  })
273
279
  })
274
280
 
275
- // Create router
276
- const routeTree = rootRoute.addChildren([previewsRoute, previewDetailRoute, ...pageRoutes])
277
- const router = createRouter({ routeTree })
281
+ // If no index page exists, create a redirect from '/' to the first page
282
+ const indexRedirectRoute = !hasIndexPage && firstPage ? createRoute({
283
+ getParentRoute: () => rootRoute,
284
+ path: '/',
285
+ component: () => <Navigate to={firstPage.route} />,
286
+ }) : null
287
+
288
+ // Not found component - redirect to first page or index
289
+ function NotFoundPage() {
290
+ const targetRoute = firstPage?.route || '/'
291
+ return <Navigate to={targetRoute} />
292
+ }
293
+
294
+ // Create router with notFoundRoute
295
+ const routeTree = rootRoute.addChildren([
296
+ previewsRoute,
297
+ previewDetailRoute,
298
+ ...(indexRedirectRoute ? [indexRedirectRoute] : []),
299
+ ...pageRoutes,
300
+ ])
301
+ const router = createRouter({
302
+ routeTree,
303
+ defaultNotFoundComponent: NotFoundPage,
304
+ })
278
305
 
279
306
  // Mount app - RouterProvider must be outermost so TanStack Router context is available
280
307
  const container = document.getElementById('root')