Skip to content

Conversation

@dwgray
Copy link
Member

@dwgray dwgray commented Oct 2, 2025

Describe the PR

Add a button to the examples in our documentation to open them in StackBlitz.

I implemented this by using the StackBlitz sdk and pulling in our existing vite template from source and substituting the demo code for the Comp.vue file in our template.

Tested in vite and build modes and all works without errors or warnings.

This only works for examples that are factored into their own files, so once this goes through I will do a pass to finish that refecotring as soon as I’ve got some cycles.

Small replication

Most of the examples in the component docs.

PR checklist

What kind of change does this PR introduce? (check at least one)

  • Bugfix 🐛 - fix(...)
  • Feature - feat(...)
  • ARIA accessibility - fix(...)
  • Documentation update - docs(...)
  • Other (please describe)

The PR fulfills these requirements:

  • Pull request title and all commits follow the Conventional Commits convention or has an override in this pull request body This is very important, as the CHANGELOG is generated from these messages, and determines the next version type. Pull requests that do not follow conventional commits or do not have an override will be denied

Summary by CodeRabbit

  • New Features

    • Docs examples now show a language label and an “Open in StackBlitz” button to launch a live playground when full source is available.
  • Bug Fixes

    • More reliable build-time reading and handling of example files with graceful fallbacks and reduced duplicate path resolution.
  • Chores

    • Added StackBlitz SDK as a dev dependency, new raw-template and Vite env type declarations, and updated TypeScript config to include them.

Copilot AI review requested due to automatic review settings October 2, 2025 00:04
@bolt-new-by-stackblitz
Copy link

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@coderabbitai
Copy link

coderabbitai bot commented Oct 2, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Reads demo source files at build time, encodes full file content as base64, injects it into HighlightCard, and adds a conditional StackBlitz launch. Adds template/raw type declarations, Vite env types, includes declarations in tsconfig, and adds @stackblitz/sdk to devDependencies.

Changes

Cohort / File(s) Summary
Docs demo container plugin
apps/docs/.vitepress/plugins/demo-container.ts
Resolve demo path earlier, read file via fs.readFileSync with try/catch, base64-encode full file content, inject fullFile (and title) into HighlightCard prefix, remove duplicate path resolution, replace @ts-ignore with @ts-expect-error.
Highlight card component
apps/docs/src/components/HighlightCard.vue
Decode base64 fullFile with UTF‑8 handling, expose hasFileContent, construct virtual project files, add conditional StackBlitz button that dynamically imports @stackblitz/sdk to open a project (with fallback URL and error logging), and adjust header UI.
Type declarations
apps/docs/src/template-types.d.ts, apps/docs/src/vite-env.d.ts
Add ambient module declarations for */templates/vite/*?raw imports (exports default string) and add triple‑slash reference to Vite client types.
TSConfig include
apps/docs/tsconfig.app.json
Add src/template-types.d.ts to include so new declarations are picked up by TypeScript.
Docs dependencies
apps/docs/package.json
Add devDependency @stackblitz/sdk ^1.11.0.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Build as VitePress Build
  participant Plugin as demo-container.ts
  participant FS as fs
  participant MD as Markdown Renderer
  participant HC as HighlightCard (attrs)

  Build->>Plugin: parse markdown/code fence tokens
  Plugin->>FS: readFile(resolvedPath) (try/catch)
  alt read success
    Plugin->>Plugin: base64-encode file -> encodedFullFile
    Plugin-->>MD: inject <HighlightCard fullFile="...b64..." title="..."> + set code src
  else read failure
    Plugin-->>MD: inject <HighlightCard> (no fullFile) and console.warn
  end
  MD-->>HC: render component with optional fullFile/title
Loading
sequenceDiagram
  autonumber
  actor User
  participant HC as HighlightCard.vue
  participant SDK as @stackblitz/sdk (dynamic)
  participant SB as stackblitz.com

  User->>HC: click "StackBlitz"
  HC->>HC: decode base64 -> fullFileContent, build project files
  HC->>SDK: import('@stackblitz/sdk')
  alt import & open ok
    SDK->>SB: openProject({ files, deps, template:'node' })
    SB-->>User: new window with project
  else error
    HC-->>User: open fallback StackBlitz URL
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • VividLemon

Poem

I nibble bytes beneath the docs' moonlight,
Base64 carrots snug, I take a flight.
I stitch a demo burrow, tidy and bright,
A click and StackBlitz blooms into sight,
Hooray — code hops free, and all feels right. 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The title clearly and concisely summarizes the primary change—enabling examples to be loaded directly into StackBlitz—and follows the Conventional Commits format, making it immediately understandable in history and changelogs.
Description Check ✅ Passed The description adheres to the repository’s template by providing a clear “Describe the PR” section, a “Small replication” note, and a properly formatted PR checklist with the required information about the change type and commit conventions.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3ed05d2 and 20ccdb2.

📒 Files selected for processing (1)
  • apps/docs/src/components/HighlightCard.vue (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/docs/src/components/HighlightCard.vue
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds StackBlitz integration to the documentation site, allowing users to directly open component examples in an online development environment. The implementation uses the StackBlitz SDK to create complete Vue projects with the existing Vite template structure.

  • Integration of StackBlitz SDK for opening examples in online editor
  • Enhancement of HighlightCard component to include StackBlitz button and project creation logic
  • Build configuration updates to handle StackBlitz template files during documentation build

Reviewed Changes

Copilot reviewed 4 out of 7 changed files in this pull request and generated 2 comments.

File Description
apps/docs/tsconfig.app.json Excludes StackBlitz template files from TypeScript compilation
apps/docs/src/components/HighlightCard.vue Adds StackBlitz button and project creation functionality with template file imports
apps/docs/package.json Adds StackBlitz SDK dependency
apps/docs/.vitepress/plugins/demo-container.ts Enhances demo container plugin to read and encode source files for StackBlitz integration
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

@pkg-pr-new
Copy link

pkg-pr-new bot commented Oct 2, 2025

bsvn-vite-ts

npm i https://pkg.pr.new/bootstrap-vue-next/bootstrap-vue-next@2869
npm i https://pkg.pr.new/bootstrap-vue-next/bootstrap-vue-next/@bootstrap-vue-next/nuxt@2869

commit: 20ccdb2

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d7d3476 and f00945c.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • apps/docs/.vitepress/plugins/demo-container.ts (2 hunks)
  • apps/docs/package.json (1 hunks)
  • apps/docs/src/components/HighlightCard.vue (1 hunks)
  • apps/docs/src/template-types.d.ts (1 hunks)
  • apps/docs/src/vite-env.d.ts (1 hunks)
  • apps/docs/tsconfig.app.json (1 hunks)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
apps/docs/src/components/HighlightCard.vue (2)

9-20: Consider adding aria-label for accessibility.

The button has a title attribute but would benefit from an aria-label to improve screen reader support, especially since the text "StackBlitz" might not convey the full action.

         <BButton
           v-if="hasFileContent"
           size="sm"
           variant="outline-primary"
           title="Open in StackBlitz"
+          aria-label="Open example in StackBlitz"
           @click="openInStackBlitz"
         >

96-123: LGTM with minor suggestion!

The StackBlitz integration is well-implemented with proper dynamic importing, error handling, and user experience considerations.

Consider making the fallback URL more specific or providing feedback to the user:

   } catch (error) {
     // eslint-disable-next-line no-console
     console.error('Failed to open StackBlitz project:', error)
-    // Fallback to basic StackBlitz
-    window.open('https://stackblitz.com/fork/vue-ts', '_blank')
+    // Fallback with user notification
+    alert('Failed to open in StackBlitz. Please try again or check your browser console for details.')
+    window.open('https://stackblitz.com/', '_blank')
   }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f00945c and 3b92912.

📒 Files selected for processing (2)
  • apps/docs/.vitepress/plugins/demo-container.ts (2 hunks)
  • apps/docs/src/components/HighlightCard.vue (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (11)
apps/docs/.vitepress/plugins/demo-container.ts (6)

4-4: LGTM!

Standard fs import appropriate for build-time file reading.


45-47: LGTM!

Path resolution correctly uses path.resolve with dirname to safely resolve relative paths while preventing directory traversal.


49-58: LGTM!

File reading logic is well-implemented with existence check, explicit UTF-8 encoding, and graceful error handling. The approach is appropriate for build-time processing.


60-62: LGTM!

Base64 encoding with explicit UTF-8 handling correctly preserves Unicode characters and matches the decoding implementation in HighlightCard.vue.


67-67: LGTM!

Base64 content injection into HTML attribute is safe (base64 alphabet is alphanumeric + /+= and doesn't require escaping) and properly integrates with the HighlightCard component.


72-73: LGTM!

Replacing @ts-ignore with @ts-expect-error is a better practice—it will error if the underlying type issue is resolved, preventing stale suppressions.

apps/docs/src/components/HighlightCard.vue (5)

30-40: LGTM!

Template file imports using the ?raw suffix are properly configured and supported by the ambient module declarations added in the PR.


41-49: LGTM!

Props interface and defaults are well-defined, allowing the component to gracefully handle cases with or without StackBlitz integration.


52-77: LGTM! Past review concern addressed.

The UTF-8-safe base64 decoding implementation correctly addresses the previous Unicode corruption issue. The cross-environment approach with proper fallbacks ensures characters like "é" and "–" are preserved in both browser and Node contexts.


80-83: LGTM!

Computed properties correctly provide reactive access to file content state and decoded content.


85-94: LGTM!

Project file structure correctly assembles a complete Vite project with the demo content substituted into src/components/Comp.vue.

Copy link
Member

@VividLemon VividLemon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Last was wrong

@VividLemon VividLemon merged commit 0206b12 into bootstrap-vue-next:main Oct 7, 2025
5 checks passed
xvaara added a commit to xvaara/bootstrap-vue-next that referenced this pull request Oct 11, 2025
* upstream/main:
  chore: release main (bootstrap-vue-next#2868)
  fix(useModalOrchestrator): circular dependency (bootstrap-vue-next#2874)
  docs(BModal): Parity pass (bootstrap-vue-next#2866)
  docs: Enable directly loading examples into StackBlitz (bootstrap-vue-next#2869)
  fix(BApp): wrap our test app in BApp in main.ts to enable easy verification of useModal, etc. (bootstrap-vue-next#2865)
  export useScrollLock() (bootstrap-vue-next#2854)
  chore: release main (bootstrap-vue-next#2858)
  fix(BToggle): stop looking for missing targets after directive is unmounted (bootstrap-vue-next#2857)
  chore: release main (bootstrap-vue-next#2851)
  Fix modal transition delays by making TransitionGroup name conditional (bootstrap-vue-next#2845)
  chore: release main (bootstrap-vue-next#2842)
  fix(BTable): events being wrongly stopped when sent from elements inside TRs (bootstrap-vue-next#2841)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants