feat(docs): embed StackBlitz examples per package#300
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis PR adds StackBlitz embeds to documentation examples by expanding the example generator to produce framework, openFile, and title metadata plus MDX pages; introducing a StackblitzEmbed component that renders embeds from example slugs; and configuring the docs sidebar and build lifecycle to integrate the generated examples. ChangesStackBlitz Example Embeds in Docs
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
www/docs/astro.config.tsOops! Something went wrong! :( ESLint: 10.2.1 Error: Cannot find module '/node_modules/@stephansama/eslint-config/dist/index.mjs' ... [truncated 540 characters] ... 265:11) scripts/src/generate-examples.tsOops! Something went wrong! :( ESLint: 10.2.1 Error: Cannot find module '/node_modules/@stephansama/eslint-config/dist/index.mjs' ... [truncated 540 characters] ... 265:11) www/docs/src/components/StackblitzEmbed.astroOops! Something went wrong! :( ESLint: 10.2.1 Error: Cannot find module '/node_modules/@stephansama/eslint-config/dist/index.mjs' ... [truncated 540 characters] ... 265:11) Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
There was a problem hiding this comment.
Code Review
This pull request introduces a new StackblitzEmbed Astro component to facilitate embedding interactive code examples directly from GitHub into the documentation. It also adds several example pages for various packages, including astro-iconify-svgmap, remark-asciinema, and typed-events, utilizing this new component. Review feedback suggests optimizing the URL parameter logic for the StackBlitz view, updating the iframe's allow attribute to support clipboard access while removing non-standard directives, and implementing internationalization for UI text to support multiple locales.
| const params = new URLSearchParams({ embed: "1", view }); | ||
| if (openFile) params.set("file", openFile); |
There was a problem hiding this comment.
The view parameter is currently included in the URL even when set to "default". StackBlitz expects either "editor" or "preview", and omitting the parameter defaults to the combined view. It's cleaner to only set the parameter if a specific view is requested.
const params = new URLSearchParams({ embed: "1" });
if (view !== "default") params.set("view", view);
if (openFile) params.set("file", openFile);
| src={embedUrl} | ||
| title={frameTitle} | ||
| loading="lazy" | ||
| allow="cross-origin-isolated" |
There was a problem hiding this comment.
The allow attribute should include clipboard-write to enable users to copy code from the StackBlitz editor. Additionally, cross-origin-isolated is not a standard directive for the Permissions Policy (the allow attribute). Cross-origin isolation for iframes is typically managed via COOP/COEP headers or the credentialless attribute.
allow="clipboard-write"
| ></iframe> | ||
| <p class="stackblitz-open"> | ||
| <a href={openUrl} target="_blank" rel="noreferrer noopener"> | ||
| Open in StackBlitz → |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/src/generate-examples.ts`:
- Around line 8-22: The file violates the project's perfectionist/sort-modules
ordering: move the exported interface Example so it appears before the local
interface StackblitzOverrides, and reorder the keys inside Example (and any
other object literal/interface declarations between lines 33-58) to match the
configured key ordering used by the project—e.g., ensure Example's properties
appear in the expected sequence (description, name, relativeDir, version, slug,
framework, openFile, title) and apply the same ordering to any other
interfaces/objects flagged by CI.
- Around line 91-101: humanizeTitle returns raw kebab-case for single-segment
slugs; update the function so the single-part path is normalized the same way as
multi-part frameworks: take parts[0] (head), replace hyphens with spaces and
apply the same title-casing regex used for `framework` (/(^|\s|-)([a-z])/g) to
capitalize letters, then return that transformed head instead of the raw
value—modify the `humanizeTitle` function (variables `parts`, `head`, `tail`,
`framework`) so both single- and multi-segment slugs are humanized consistently.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 23f583f3-094b-47f0-bdec-cdcaae64a359
📒 Files selected for processing (5)
.gitignorescripts/src/generate-examples.tswww/docs/astro.config.tswww/docs/package.jsonwww/docs/src/components/StackblitzEmbed.astro
| interface StackblitzOverrides { | ||
| openFile?: string; | ||
| title?: string; | ||
| } | ||
|
|
||
| export interface Example { | ||
| description: string | undefined; | ||
| name: string; | ||
| relativeDir: string; | ||
| version: string; | ||
| slug: string; | ||
| framework: string; | ||
| openFile: string | undefined; | ||
| title: string; | ||
| } |
There was a problem hiding this comment.
Fix perfectionist/sort-modules ordering violations blocking CI.
This file still violates the active sort rules (already failing in CI). Please reorder declarations/object keys to match the configured order (e.g., export interface Example before local interfaces, and object keys in expected order).
Suggested ordering fix (example)
-interface StackblitzOverrides {
- openFile?: string;
- title?: string;
-}
-
export interface Example {
description: string | undefined;
+ framework: string;
name: string;
+ openFile: string | undefined;
relativeDir: string;
- version: string;
slug: string;
- framework: string;
- openFile: string | undefined;
title: string;
+ version: string;
+}
+
+interface StackblitzOverrides {
+ openFile?: string;
+ title?: string;
}
const FRAMEWORK_OPEN_FILES: Array<{
- framework: string;
- deps: string[];
candidates: string[];
+ deps: string[];
+ framework: string;
}> = [
{
- framework: "sveltekit",
- deps: ["`@sveltejs/kit`"],
candidates: ["src/routes/+page.svelte"],
+ deps: ["`@sveltejs/kit`"],
+ framework: "sveltekit",
},Also applies to: 33-58
🧰 Tools
🪛 GitHub Actions: 🦋 Changesets Release / 1_Examples _ Test.txt
[error] 13-13: ESLint (perfectionist/sort-modules): Expected "Example" (export-interface) to come before "StackblitzOverrides" (interface).
🪛 GitHub Actions: 🦋 Changesets Release / Examples _ Test
[error] 13-13: ESLint perfectionist/sort-modules: Expected "Example" (export-interface) to come before "StackblitzOverrides" (interface).
🪛 GitHub Check: Examples / Test
[failure] 19-19:
Expected "framework" to come before "slug"
[failure] 18-18:
Expected "slug" to come before "version"
[failure] 13-13:
Expected "Example" (export-interface) to come before "StackblitzOverrides" (interface)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/src/generate-examples.ts` around lines 8 - 22, The file violates the
project's perfectionist/sort-modules ordering: move the exported interface
Example so it appears before the local interface StackblitzOverrides, and
reorder the keys inside Example (and any other object literal/interface
declarations between lines 33-58) to match the configured key ordering used by
the project—e.g., ensure Example's properties appear in the expected sequence
(description, name, relativeDir, version, slug, framework, openFile, title) and
apply the same ordering to any other interfaces/objects flagged by CI.
| function humanizeTitle(slug: string): string { | ||
| const parts = slug.split("/"); | ||
| if (parts.length === 1) return parts[0]!; | ||
| const [head, ...tail] = parts; | ||
| const framework = tail | ||
| .join(" ") | ||
| .replace( | ||
| /(^|\s|-)([a-z])/g, | ||
| (_, sep, letter) => `${sep}${letter.toUpperCase()}`, | ||
| ); | ||
| return `${head} — ${framework}`; |
There was a problem hiding this comment.
Humanize single-segment example titles too.
humanizeTitle() returns raw kebab-case for one-part slugs, so cards/pages can show unformatted titles.
Suggested fix
function humanizeTitle(slug: string): string {
+ const humanize = (value: string) =>
+ value
+ .replace(/-/g, " ")
+ .replace(/\b([a-z])/g, (m) => m.toUpperCase());
+
const parts = slug.split("/");
- if (parts.length === 1) return parts[0]!;
+ if (parts.length === 1) return humanize(parts[0]!);
const [head, ...tail] = parts;
const framework = tail
.join(" ")
.replace(
/(^|\s|-)([a-z])/g,
(_, sep, letter) => `${sep}${letter.toUpperCase()}`,
);
- return `${head} — ${framework}`;
+ return `${humanize(head)} — ${framework}`;
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/src/generate-examples.ts` around lines 91 - 101, humanizeTitle
returns raw kebab-case for single-segment slugs; update the function so the
single-part path is normalized the same way as multi-part frameworks: take
parts[0] (head), replace hyphens with spaces and apply the same title-casing
regex used for `framework` (/(^|\s|-)([a-z])/g) to capitalize letters, then
return that transformed head instead of the raw value—modify the `humanizeTitle`
function (variables `parts`, `head`, `tail`, `framework`) so both single- and
multi-segment slugs are humanized consistently.
Closes STE-189
Adds a reusable
<StackblitzEmbed>Astro component and per-package example MDX pages underwww/docs/src/content/docs/examples/. Each page embeds the sandbox via the StackBlitz "open on GitHub" URL — no SDK dep, pure URL construction.Files
www/docs/src/components/StackblitzEmbed.astro— props:repo,dir,branch?,openFile?,view?,height?,title?. Renders an iframe + an "Open in StackBlitz" link.www/docs/src/content/docs/examples/:astro-iconify-svgmap.mdx— astro exampleremark-asciinema.mdx— astro examplesvelte-social-share-links/{astro,svelte-kit}.mdxtyped-events/{react,vanilla}.mdxAcceptance criteria
<StackblitzEmbed>ships atwww/docs/src/components/StackblitzEmbed.astroexamples/package has an MDX page that embeds its sandbox<iframe src="https://stackblitz.com/github/..."markup (URL-based, no SDK)content/docs/examples/, so the sidebar entry surfaces automatically; explicit grouping inastro.config.tscan be added later if a custom label is needed