feat(examples): add next-runtime-snapshot Next.js example + docs#22
Merged
Conversation
Adds examples/next-runtime-snapshot proving Next.js App Router works as a devframe SPA via static export — three RPC functions (system / memory / env) surface host Node runtime info, exercising static + query types and valibot-validated args. Documents the Next.js SPA setup recipe alongside the existing Nuxt one, broadens the pnpm frontend catalog to React + Next, and ships vitest + Playwright coverage.
✅ Deploy Preview for devfra ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Pull request overview
Adds a new end-to-end Next.js App Router example (examples/next-runtime-snapshot) to demonstrate using a Next.js static export as a devframe SPA, plus accompanying docs, tooling wiring, and test coverage (Vitest + Playwright) integrated into the monorepo.
Changes:
- Introduces
examples/next-runtime-snapshot(Next.js static export SPA) with three RPC functions (system,memory,env) and CLI wiring. - Expands the monorepo test/build setup to include the new example (turbo tasks, vitest workspace, Playwright webServers + e2e specs).
- Updates docs to add a “Next.js SPA setup” recipe and lists the new example in “built-with”.
Reviewed changes
Copilot reviewed 26 out of 27 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| vitest.config.ts | Adds the new example to the Vitest workspace list. |
| turbo.json | Adds turbo build and cli:build tasks for the new example. |
| tests/e2e/next-runtime-snapshot-static.spec.ts | Adds Playwright coverage for the static-export mode. |
| tests/e2e/next-runtime-snapshot-dev.spec.ts | Adds Playwright coverage for dev (websocket) mode. |
| pnpm-workspace.yaml | Extends catalogs for Next/React and adjusts build-allowlist. |
| pnpm-lock.yaml | Locks newly introduced dependencies (Next/React ecosystem + transitive deps). |
| playwright.config.ts | Registers dev + static webServers for the new example. |
| examples/next-runtime-snapshot/tsconfig.json | Adds TS configuration for the example package. |
| examples/next-runtime-snapshot/tests/next-runtime-snapshot.test.ts | Adds Vitest coverage for RPC behavior and connection meta. |
| examples/next-runtime-snapshot/tests/_utils.ts | Adds an in-process server bootstrap helper for tests. |
| examples/next-runtime-snapshot/src/devframe.ts | Defines the devframe + RPC functions (system/memory/env) and SPA config. |
| examples/next-runtime-snapshot/src/client/tsconfig.json | Adds TS config for the Next.js client project. |
| examples/next-runtime-snapshot/src/client/next.config.mjs | Configures Next.js for static export compatible with devframe mounting. |
| examples/next-runtime-snapshot/src/client/app/page.tsx | Implements the main page UI and status bar. |
| examples/next-runtime-snapshot/src/client/app/layout.tsx | Adds app layout + metadata for the Next.js app. |
| examples/next-runtime-snapshot/src/client/app/globals.css | Adds example styling for the UI. |
| examples/next-runtime-snapshot/src/client/app/components/snapshot-system.tsx | UI card for the system RPC. |
| examples/next-runtime-snapshot/src/client/app/components/snapshot-memory.tsx | UI card for the memory RPC + refresh. |
| examples/next-runtime-snapshot/src/client/app/components/snapshot-env.tsx | UI card for the env RPC + debounced regex filter. |
| examples/next-runtime-snapshot/src/client/app/components/connect.tsx | Connects to devframe once and exposes RPC via React context. |
| examples/next-runtime-snapshot/README.md | Documents what the example demonstrates and how to run/build it. |
| examples/next-runtime-snapshot/package.json | Adds scripts/deps for building and running the example. |
| examples/next-runtime-snapshot/bin.mjs | Adds the CLI entrypoint for dev/build modes. |
| examples/next-runtime-snapshot/.gitignore | Ignores Next build outputs and dist artifacts. |
| eslint.config.js | Ignores Next build artifacts (.next, out, next-env.d.ts). |
| docs/guide/standalone-cli.md | Adds a Next.js SPA setup recipe alongside the existing Nuxt guidance. |
| docs/guide/built-with.md | Lists the new Next.js example among end-to-end demos. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+121
to
+131
| if (pattern) { | ||
| try { | ||
| regex = new RegExp(pattern, 'i') | ||
| } | ||
| catch { | ||
| regex = null | ||
| } | ||
| } | ||
| const keys = Object.keys(process.env).sort() | ||
| const matched = regex ? keys.filter(k => regex.test(k)) : keys | ||
| const entries = matched.slice(0, limit).map(k => redact(k, process.env[k] ?? '')) |
Comment on lines
+50
to
+57
| // SPA mount is conditional — RPC-only tests don't need the built dist. | ||
| // Tests that fetch HTML should run `pnpm run build` first. | ||
| try { | ||
| mountStaticHandler(app, basePath, resolve(distDir)) | ||
| } | ||
| catch { | ||
| // No dist yet; that's fine for RPC-only tests. | ||
| } |
Comment on lines
+33
to
+44
| <dl className="kv"> | ||
| <span className="k">node</span> | ||
| <span className="v">{info.node}</span> | ||
| <span className="k">platform</span> | ||
| <span className="v">{`${info.platform} (${info.arch})`}</span> | ||
| <span className="k">pid</span> | ||
| <span className="v">{info.pid}</span> | ||
| <span className="k">cwd</span> | ||
| <span className="v">{info.cwd}</span> | ||
| <span className="k">started</span> | ||
| <span className="v">{formatStartedAt(info.startedAt)}</span> | ||
| </dl> |
Comment on lines
+58
to
+71
| <dl className="kv"> | ||
| <span className="k">uptime</span> | ||
| <span className="v">{fmtUptime(snap.uptimeSeconds)}</span> | ||
| <span className="k">rss</span> | ||
| <span className="v">{fmtBytes(snap.memory.rss)}</span> | ||
| <span className="k">heap used</span> | ||
| <span className="v">{fmtBytes(snap.memory.heapUsed)}</span> | ||
| <span className="k">heap total</span> | ||
| <span className="v">{fmtBytes(snap.memory.heapTotal)}</span> | ||
| <span className="k">external</span> | ||
| <span className="v">{fmtBytes(snap.memory.external)}</span> | ||
| <span className="k">array buffers</span> | ||
| <span className="v">{fmtBytes(snap.memory.arrayBuffers)}</span> | ||
| </dl> |
Comment on lines
+46
to
+51
| <input | ||
| type="text" | ||
| value={pattern} | ||
| onChange={e => setPattern(e.target.value)} | ||
| placeholder="Regex filter (case-insensitive) — e.g. NODE | PATH | HOME" | ||
| /> |
Comment on lines
+22
to
+23
| const initialRss = await memCard.locator('.kv .v').nth(1).textContent() | ||
| expect(initialRss).toMatch(/\d+(?:\.\d+)?\s*MB/) |
| ```json [package.json] | ||
| { | ||
| "scripts": { | ||
| "build": "next build src/client && rm -rf dist/client && cp -r src/client/out dist/client" |
…shot - Invalid regex pattern in `env` RPC now matches nothing rather than silently widening to all keys (could leak vars the redaction heuristic doesn't catch). Adds a vitest case to cover. - Drop dead try/catch around `mountStaticHandler()` in test utils — it doesn't throw on missing distDir. - Replace `<dl>` with `<span>` children with `<div className="kv">` in the system + memory cards (invalid definition-list structure). - Add `aria-label` to the env filter input. - Coalesce `Locator.textContent()` to `''` in the Playwright dev spec. - Match the example's actual build script in the docs snippet (`mkdir -p dist` before `cp -r`).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
examples/next-runtime-snapshotproves Next.js App Router works as a devframe SPA via static export (output: 'export',assetPrefix: '.',trailingSlash: true); three RPC functions surface host Node runtime info —system(static),memory(query), andenv(query with valibot-validated args + secret redaction).docs/guide/standalone-cli.mdalongside the existing Nuxt one, lists the example inbuilt-with.md, and broadens the pnpmfrontendcatalog to React + Next.turbo.json,vitest.config.ts, andplaywright.config.ts, with eslint ignores extended for.next/out/next-env.d.ts.Test plan
pnpm test— 31 files / 328 tests passing, including the new vitest suitepnpm lint && pnpm typecheck— cleanpnpm -C docs run docs:build— VitePress builds cleanly with the new recipepnpm -C examples/next-runtime-snapshot run build— Next.js static export →dist/client/node examples/next-runtime-snapshot/bin.mjs— dev server onhttp://localhost:9899/__next-runtime-snapshot/node examples/next-runtime-snapshot/bin.mjs build --out-dir dist/static— static dump emits__connection.json+ bakedsystemsnapshotpnpm test:e2e— Playwright e2e suite (verified locally against manually-booted servers)