Feature AI prompts in home Quick Start + add /prompts page#125
Conversation
Brainstormed spec: replace home Quick Start command cards with grounded AI-agent prompt cards (RSC first, marquee), and add a /prompts page library. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Task-by-task plan: prompt data module, PromptCard component, /prompts page, navbar link, home Quick Start refactor, and full-build verification. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
WalkthroughThis PR introduces a copy-able, doc-grounded AI prompt library and refactors home Quick Start to use reusable prompt cards. Changes include a centralized prompts data module with curated subsets, a PromptCard component with clipboard copy and guide links, a new ChangesAI Prompts Feature
🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 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)
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.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issue.
Reviewed by Cursor Bugbot for commit cd95434. Configure here.
| try { | ||
| await navigator.clipboard.writeText(prompt.prompt); | ||
| setCopied(true); | ||
| window.setTimeout(() => setCopied(false), 2000); |
There was a problem hiding this comment.
Copy timer stacks on clicks
Medium Severity
Each successful copy schedules a two-second setTimeout to reset the button label, but earlier timers are never cleared. A second copy within that window can show Copied briefly, then revert to Copy prompt while the latest copy is still within its feedback period, and navigating away can trigger a state update after unmount.
Reviewed by Cursor Bugbot for commit cd95434. Configure here.
Greptile SummaryThis PR replaces the home page Quick Start shell-command cards with copy-able AI-agent prompt cards and adds a new
Confidence Score: 4/5Safe to merge; all changes are additive UI features with clean CSS cleanup and no logic regressions. The implementation is well-structured and follows established codebase patterns throughout. The only notable issue is in PromptCard: the setTimeout ID is not stored, so clicking 'Copy prompt' multiple times within 2 seconds stacks timers and resets the label earlier than expected. This is a minor UX polish issue, not a functional breakage. Everything else — data module, page structure, CSS changes, and navbar addition — looks correct. prototypes/docusaurus/src/components/PromptCard/index.tsx — the timer-stacking fix would improve UX polish on the copy button. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[prompts.ts\ndata module] --> B[homePrompts\n3 curated IDs]
A --> C[prompts\n11 entries]
A --> D[promptGroups\n5 categories]
B --> E[index.tsx\nQuickStartSection]
C --> F[prompts.tsx\nPromptsPage]
D --> F
E --> G[PromptCard\ncomponent]
F --> G
G --> H[navigator.clipboard\n.writeText]
G --> I[Docusaurus Link\nOpen guide →]
style A fill:#f0f4ff,stroke:#4a6cf7
style G fill:#f0f4ff,stroke:#4a6cf7
|
| import {useState, type ReactNode} from 'react'; | ||
| import Link from '@docusaurus/Link'; | ||
|
|
||
| import type {Prompt} from '../../constants/prompts'; | ||
| import styles from './styles.module.css'; | ||
|
|
||
| export default function PromptCard({prompt}: {prompt: Prompt}): ReactNode { | ||
| const [copied, setCopied] = useState(false); | ||
|
|
||
| async function handleCopy() { | ||
| try { | ||
| await navigator.clipboard.writeText(prompt.prompt); | ||
| setCopied(true); | ||
| window.setTimeout(() => setCopied(false), 2000); | ||
| } catch (error) { | ||
| // Clipboard API can be unavailable (insecure context / denied permission). | ||
| // The prompt text is visible on the card, so the user can still select it. | ||
| // Surface the reason instead of failing silently. | ||
| console.warn('Copy to clipboard failed:', error); | ||
| } | ||
| } |
There was a problem hiding this comment.
Using
window.setTimeout is unnecessary here — plain setTimeout is idiomatic in React components and avoids any potential confusion in environments where window may not be defined (e.g., SSR execution paths). Additionally, storing the returned timer ID in a useRef and cancelling it before each new call prevents multiple in-flight timers from resetting the "Copied" label prematurely when the button is clicked in quick succession.
| import {useState, type ReactNode} from 'react'; | |
| import Link from '@docusaurus/Link'; | |
| import type {Prompt} from '../../constants/prompts'; | |
| import styles from './styles.module.css'; | |
| export default function PromptCard({prompt}: {prompt: Prompt}): ReactNode { | |
| const [copied, setCopied] = useState(false); | |
| async function handleCopy() { | |
| try { | |
| await navigator.clipboard.writeText(prompt.prompt); | |
| setCopied(true); | |
| window.setTimeout(() => setCopied(false), 2000); | |
| } catch (error) { | |
| // Clipboard API can be unavailable (insecure context / denied permission). | |
| // The prompt text is visible on the card, so the user can still select it. | |
| // Surface the reason instead of failing silently. | |
| console.warn('Copy to clipboard failed:', error); | |
| } | |
| } | |
| import {useState, useRef, type ReactNode} from 'react'; | |
| import Link from '@docusaurus/Link'; | |
| import type {Prompt} from '../../constants/prompts'; | |
| import styles from './styles.module.css'; | |
| export default function PromptCard({prompt}: {prompt: Prompt}): ReactNode { | |
| const [copied, setCopied] = useState(false); | |
| const resetTimer = useRef<ReturnType<typeof setTimeout> | null>(null); | |
| async function handleCopy() { | |
| try { | |
| await navigator.clipboard.writeText(prompt.prompt); | |
| setCopied(true); | |
| if (resetTimer.current !== null) { | |
| clearTimeout(resetTimer.current); | |
| } | |
| resetTimer.current = setTimeout(() => setCopied(false), 2000); | |
| } catch (error) { | |
| // Clipboard API can be unavailable (insecure context / denied permission). | |
| // The prompt text is visible on the card, so the user can still select it. | |
| // Surface the reason instead of failing silently. | |
| console.warn('Copy to clipboard failed:', error); | |
| } | |
| } |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
prototypes/docusaurus/src/pages/prompts.tsx (1)
45-45:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd a trailing newline at end of file.
Please add a final newline for consistency with repo-wide formatting rules.
As per coding guidelines: "Ensure all files end with a newline."
🤖 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 `@prototypes/docusaurus/src/pages/prompts.tsx` at line 45, The file prototypes/docusaurus/src/pages/prompts.tsx is missing a trailing newline at EOF; open prompts.tsx (the Prompts page component / default export) and add a single final newline character at the end of the file so it ends with a newline to satisfy the repo formatting rules.Source: Coding guidelines
docs/superpowers/specs/2026-06-04-home-quick-start-prompts-design.md (1)
149-149:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd a trailing newline at end of file.
Please end this markdown file with a newline to match repo-wide file rules.
As per coding guidelines: "Ensure all files end with a newline."
🤖 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 `@docs/superpowers/specs/2026-06-04-home-quick-start-prompts-design.md` at line 149, Add a single trailing newline character at the end of the markdown file 2026-06-04-home-quick-start-prompts-design.md so the file ends with a blank line; open the file, move to EOF, and insert a newline (save) to satisfy the repo-wide rule that all files must end with a newline.Source: Coding guidelines
prototypes/docusaurus/src/pages/prompts.module.css (1)
53-53:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd a trailing newline at end of file.
This file should end with a newline to satisfy the global file guideline.
As per coding guidelines: "Ensure all files end with a newline."
🤖 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 `@prototypes/docusaurus/src/pages/prompts.module.css` at line 53, Add a trailing newline to the end of prompts.module.css so the file terminates with a single newline character; open prompts.module.css and ensure the final line ends with '\n' (no extra characters) to satisfy the global file guideline requiring all files to end with a newline.Source: Coding guidelines
prototypes/docusaurus/src/components/PromptCard/styles.module.css (1)
60-60:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd a trailing newline at end of file.
This CSS module should end with a newline to comply with repository rules.
As per coding guidelines: "Ensure all files end with a newline."
🤖 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 `@prototypes/docusaurus/src/components/PromptCard/styles.module.css` at line 60, Add a single trailing newline character at the end of the PromptCard CSS module (styles.module.css) so the file ends with a newline per repository guidelines; open the PromptCard/styles.module.css file and ensure the final line is terminated with a newline (save the file so the editor writes the EOF newline).Source: Coding guidelines
docs/superpowers/plans/2026-06-04-home-quick-start-prompts.md (1)
777-777:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd a trailing newline at end of file.
The file currently ends without a final newline.
As per coding guidelines: "Ensure all files end with a newline."
🤖 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 `@docs/superpowers/plans/2026-06-04-home-quick-start-prompts.md` at line 777, The Markdown document 2026-06-04-home-quick-start-prompts.md is missing a final newline; fix it by appending a trailing newline character at the end of the file (ensure your editor/save settings add a final newline) and re-save/commit so the file ends with a single terminating newline.Source: Coding guidelines
🤖 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 `@docs/superpowers/plans/2026-06-04-home-quick-start-prompts.md`:
- Line 11: Change the "Verification model (read first)" heading from level 3
(###) to level 2 (##) to fix the heading level jump and satisfy markdownlint
MD001; locate the heading text "Verification model (read first)" and replace the
leading "###" with "##".
In `@prototypes/docusaurus/src/components/PromptCard/index.tsx`:
- Around line 1-37: The file ends without a trailing newline; add a single
newline character at EOF so the module (PromptCard component) file conforms to
the coding guideline—open the PromptCard component file (export default function
PromptCard) and ensure there is a final blank line after the last closing
brace/parenthesis.
- Around line 10-21: The handleCopy function sets a 2s timeout to reset
setCopied but does not clear it on unmount; capture the timer ID (from
window.setTimeout) into a ref (e.g., copyTimeoutRef) when calling setTimeout
inside handleCopy and add a useEffect cleanup that clears the timeout
(clearTimeout(copyTimeoutRef.current)) on unmount to prevent calling setCopied
on an unmounted component; ensure you reset/clear the ref when the timeout fires
and also clear it in the catch path if needed.
In `@prototypes/docusaurus/src/constants/prompts.ts`:
- Around line 1-167: The file is missing a trailing newline; add a single
newline character at EOF so the file ends with a newline (ensure the last line
after the export const promptGroups block ends with a newline). Locate the file
by symbols such as SITE_URL, prompts, homePrompts, or promptGroups and append
the newline to satisfy coding guidelines.
---
Outside diff comments:
In `@docs/superpowers/plans/2026-06-04-home-quick-start-prompts.md`:
- Line 777: The Markdown document 2026-06-04-home-quick-start-prompts.md is
missing a final newline; fix it by appending a trailing newline character at the
end of the file (ensure your editor/save settings add a final newline) and
re-save/commit so the file ends with a single terminating newline.
In `@docs/superpowers/specs/2026-06-04-home-quick-start-prompts-design.md`:
- Line 149: Add a single trailing newline character at the end of the markdown
file 2026-06-04-home-quick-start-prompts-design.md so the file ends with a blank
line; open the file, move to EOF, and insert a newline (save) to satisfy the
repo-wide rule that all files must end with a newline.
In `@prototypes/docusaurus/src/components/PromptCard/styles.module.css`:
- Line 60: Add a single trailing newline character at the end of the PromptCard
CSS module (styles.module.css) so the file ends with a newline per repository
guidelines; open the PromptCard/styles.module.css file and ensure the final line
is terminated with a newline (save the file so the editor writes the EOF
newline).
In `@prototypes/docusaurus/src/pages/prompts.module.css`:
- Line 53: Add a trailing newline to the end of prompts.module.css so the file
terminates with a single newline character; open prompts.module.css and ensure
the final line ends with '\n' (no extra characters) to satisfy the global file
guideline requiring all files to end with a newline.
In `@prototypes/docusaurus/src/pages/prompts.tsx`:
- Line 45: The file prototypes/docusaurus/src/pages/prompts.tsx is missing a
trailing newline at EOF; open prompts.tsx (the Prompts page component / default
export) and add a single final newline character at the end of the file so it
ends with a newline to satisfy the repo formatting rules.
🪄 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: CHILL
Plan: Pro
Run ID: 43ab9248-6d8d-4619-8ca3-72887bdf881f
📒 Files selected for processing (10)
docs/superpowers/plans/2026-06-04-home-quick-start-prompts.mddocs/superpowers/specs/2026-06-04-home-quick-start-prompts-design.mdprototypes/docusaurus/docusaurus.config.tsprototypes/docusaurus/src/components/PromptCard/index.tsxprototypes/docusaurus/src/components/PromptCard/styles.module.cssprototypes/docusaurus/src/constants/prompts.tsprototypes/docusaurus/src/pages/index.module.cssprototypes/docusaurus/src/pages/index.tsxprototypes/docusaurus/src/pages/prompts.module.cssprototypes/docusaurus/src/pages/prompts.tsx
|
|
||
| **Tech Stack:** Docusaurus 3 (React + TypeScript), CSS Modules. Spec: `docs/superpowers/specs/2026-06-04-home-quick-start-prompts-design.md`. | ||
|
|
||
| ### Verification model (read first) |
There was a problem hiding this comment.
Fix heading level jump (# → ###).
Line 11 should be an ## heading to avoid skipping levels and to satisfy markdownlint MD001.
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 11-11: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3
(MD001, heading-increment)
🤖 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 `@docs/superpowers/plans/2026-06-04-home-quick-start-prompts.md` at line 11,
Change the "Verification model (read first)" heading from level 3 (###) to level
2 (##) to fix the heading level jump and satisfy markdownlint MD001; locate the
heading text "Verification model (read first)" and replace the leading "###"
with "##".
Source: Linters/SAST tools
| import {useState, type ReactNode} from 'react'; | ||
| import Link from '@docusaurus/Link'; | ||
|
|
||
| import type {Prompt} from '../../constants/prompts'; | ||
| import styles from './styles.module.css'; | ||
|
|
||
| export default function PromptCard({prompt}: {prompt: Prompt}): ReactNode { | ||
| const [copied, setCopied] = useState(false); | ||
|
|
||
| async function handleCopy() { | ||
| try { | ||
| await navigator.clipboard.writeText(prompt.prompt); | ||
| setCopied(true); | ||
| window.setTimeout(() => setCopied(false), 2000); | ||
| } catch (error) { | ||
| // Clipboard API can be unavailable (insecure context / denied permission). | ||
| // The prompt text is visible on the card, so the user can still select it. | ||
| // Surface the reason instead of failing silently. | ||
| console.warn('Copy to clipboard failed:', error); | ||
| } | ||
| } | ||
|
|
||
| return ( | ||
| <article className={styles.card}> | ||
| <h3 className={styles.title}>{prompt.title}</h3> | ||
| <p className={styles.prompt}>{prompt.prompt}</p> | ||
| <div className={styles.actions}> | ||
| <button type="button" className={styles.copyButton} onClick={handleCopy}> | ||
| {copied ? 'Copied' : 'Copy prompt'} | ||
| </button> | ||
| <Link className={styles.guideLink} to={prompt.href}> | ||
| Open guide → | ||
| </Link> | ||
| </div> | ||
| </article> | ||
| ); | ||
| } |
There was a problem hiding this comment.
Add missing newline at end of file.
As per coding guidelines, all files must end with a newline. The file currently ends at line 37 without a trailing newline.
🤖 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 `@prototypes/docusaurus/src/components/PromptCard/index.tsx` around lines 1 -
37, The file ends without a trailing newline; add a single newline character at
EOF so the module (PromptCard component) file conforms to the coding
guideline—open the PromptCard component file (export default function
PromptCard) and ensure there is a final blank line after the last closing
brace/parenthesis.
Source: Coding guidelines
| async function handleCopy() { | ||
| try { | ||
| await navigator.clipboard.writeText(prompt.prompt); | ||
| setCopied(true); | ||
| window.setTimeout(() => setCopied(false), 2000); | ||
| } catch (error) { | ||
| // Clipboard API can be unavailable (insecure context / denied permission). | ||
| // The prompt text is visible on the card, so the user can still select it. | ||
| // Surface the reason instead of failing silently. | ||
| console.warn('Copy to clipboard failed:', error); | ||
| } | ||
| } |
There was a problem hiding this comment.
Clean up the timeout on unmount to prevent memory leaks.
The setTimeout callback at line 14 will execute even if the component unmounts before the 2-second delay completes. This can cause a "setState on unmounted component" warning and a minor memory leak.
🛡️ Recommended fix using useEffect cleanup
export default function PromptCard({prompt}: {prompt: Prompt}): ReactNode {
const [copied, setCopied] = useState(false);
async function handleCopy() {
try {
await navigator.clipboard.writeText(prompt.prompt);
setCopied(true);
- window.setTimeout(() => setCopied(false), 2000);
} catch (error) {
// Clipboard API can be unavailable (insecure context / denied permission).
// The prompt text is visible on the card, so the user can still select it.
// Surface the reason instead of failing silently.
console.warn('Copy to clipboard failed:', error);
}
}
+ React.useEffect(() => {
+ if (copied) {
+ const timer = window.setTimeout(() => setCopied(false), 2000);
+ return () => window.clearTimeout(timer);
+ }
+ }, [copied]);
+
return (Alternatively, store the timer ID in a ref and clear it in a cleanup effect, or accept the 2-second window as low-risk.
🤖 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 `@prototypes/docusaurus/src/components/PromptCard/index.tsx` around lines 10 -
21, The handleCopy function sets a 2s timeout to reset setCopied but does not
clear it on unmount; capture the timer ID (from window.setTimeout) into a ref
(e.g., copyTimeoutRef) when calling setTimeout inside handleCopy and add a
useEffect cleanup that clears the timeout (clearTimeout(copyTimeoutRef.current))
on unmount to prevent calling setCopied on an unmounted component; ensure you
reset/clear the ref when the timeout fires and also clear it in the catch path
if needed.
| import {docsRoutes} from './docsRoutes'; | ||
|
|
||
| /** Canonical site origin; matches `url` in docusaurus.config.ts. */ | ||
| export const SITE_URL = 'https://reactonrails.com'; | ||
|
|
||
| /** Shown once per surface (home Quick Start + /prompts hero). */ | ||
| export const agentNote = | ||
| "Paste into Cursor, Claude Code, Copilot, or any AI assistant. Each prompt points the agent at the official docs so it doesn't guess."; | ||
|
|
||
| export type PromptCategory = | ||
| | 'get-started' | ||
| | 'server-rendering' | ||
| | 'migrate' | ||
| | 'features' | ||
| | 'production'; | ||
|
|
||
| export type Prompt = { | ||
| /** Stable slug; used as React key and to select the homepage subset. */ | ||
| id: string; | ||
| title: string; | ||
| /** Copy-able prompt text. Embeds an absolute docs URL so the agent grounds itself. */ | ||
| prompt: string; | ||
| /** Docs route the "Open guide →" link points to (relative; from docsRoutes). */ | ||
| href: string; | ||
| category: PromptCategory; | ||
| }; | ||
|
|
||
| /** Absolute docs URL embedded in prompt text so agents fetch the real guide. */ | ||
| function docUrl(route: string): string { | ||
| return `${SITE_URL}${route}`; | ||
| } | ||
|
|
||
| export const prompts: Prompt[] = [ | ||
| { | ||
| id: 'turn-on-rsc', | ||
| title: 'Turn on React Server Components', | ||
| prompt: `Turn on React Server Components in my React on Rails app (no license required). Follow ${docUrl( | ||
| docsRoutes.proReactServerComponents, | ||
| )} exactly, including the renderer and packer setup it specifies.`, | ||
| href: docsRoutes.proReactServerComponents, | ||
| category: 'server-rendering', | ||
| }, | ||
| { | ||
| id: 'create-app', | ||
| title: 'Start a new app', | ||
| prompt: `Set up a new Rails app with React on Rails, using TypeScript and server-side rendering. Follow the official guide at ${docUrl( | ||
| docsRoutes.createApp, | ||
| )} and use the exact commands and versions it specifies — don't improvise.`, | ||
| href: docsRoutes.createApp, | ||
| category: 'get-started', | ||
| }, | ||
| { | ||
| id: 'install-existing', | ||
| title: 'Add to an existing Rails app', | ||
| prompt: `Add React on Rails to my existing Rails app with TypeScript, keeping my current routes and conventions. Follow ${docUrl( | ||
| docsRoutes.installExistingApp, | ||
| )} and don't change any gem or package versions it doesn't tell you to.`, | ||
| href: docsRoutes.installExistingApp, | ||
| category: 'get-started', | ||
| }, | ||
| { | ||
| id: 'streaming-ssr', | ||
| title: 'Add streaming SSR', | ||
| prompt: `Add streaming server-side rendering to my React on Rails app. Follow ${docUrl( | ||
| docsRoutes.proStreamingSsr, | ||
| )} exactly and don't change versions it doesn't ask you to.`, | ||
| href: docsRoutes.proStreamingSsr, | ||
| category: 'server-rendering', | ||
| }, | ||
| { | ||
| id: 'async-rendering', | ||
| title: 'Use async/Suspense rendering', | ||
| prompt: `Set up async (Suspense) rendering for a React on Rails component. Follow ${docUrl( | ||
| docsRoutes.proAsyncRendering, | ||
| )} exactly.`, | ||
| href: docsRoutes.proAsyncRendering, | ||
| category: 'server-rendering', | ||
| }, | ||
| { | ||
| id: 'migrate-react-rails', | ||
| title: 'Migrate from react-rails', | ||
| prompt: `Migrate my app from react-rails to React on Rails, keeping my existing components working. Follow ${docUrl( | ||
| docsRoutes.migrateFromReactRails, | ||
| )} and don't skip any step it lists.`, | ||
| href: docsRoutes.migrateFromReactRails, | ||
| category: 'migrate', | ||
| }, | ||
| { | ||
| id: 'code-splitting', | ||
| title: 'Add code splitting', | ||
| prompt: `Add code splitting / lazy loading to my React on Rails components. Follow ${docUrl( | ||
| docsRoutes.codeSplitting, | ||
| )} exactly.`, | ||
| href: docsRoutes.codeSplitting, | ||
| category: 'features', | ||
| }, | ||
| { | ||
| id: 'oss-vs-pro', | ||
| title: 'Evaluate OSS vs Pro', | ||
| prompt: `Review my React on Rails setup and tell me whether OSS or Pro fits my workload, citing the tradeoffs. Base your answer on ${docUrl( | ||
| docsRoutes.ossVsPro, | ||
| )}.`, | ||
| href: docsRoutes.ossVsPro, | ||
| category: 'production', | ||
| }, | ||
| { | ||
| id: 'node-renderer', | ||
| title: 'Set up the Node renderer', | ||
| prompt: `Set up the React on Rails Pro Node renderer for server rendering. Follow ${docUrl( | ||
| docsRoutes.proNodeRenderer, | ||
| )} exactly, including the configuration it specifies.`, | ||
| href: docsRoutes.proNodeRenderer, | ||
| category: 'production', | ||
| }, | ||
| { | ||
| id: 'fragment-caching', | ||
| title: 'Add fragment caching', | ||
| prompt: `Add fragment caching to my server-rendered React on Rails components. Follow ${docUrl( | ||
| docsRoutes.proFragmentCaching, | ||
| )} exactly.`, | ||
| href: docsRoutes.proFragmentCaching, | ||
| category: 'production', | ||
| }, | ||
| { | ||
| id: 'upgrade-to-pro', | ||
| title: 'Get a production license / upgrade to Pro', | ||
| prompt: `Walk me through upgrading my React on Rails app to Pro and getting a production license. Follow ${docUrl( | ||
| docsRoutes.proUpgrade, | ||
| )}.`, | ||
| href: docsRoutes.proUpgrade, | ||
| category: 'production', | ||
| }, | ||
| ]; | ||
|
|
||
| /** Curated, ordered subset for the home Quick Start: RSC first (marquee). */ | ||
| const homePromptIds = ['turn-on-rsc', 'create-app', 'install-existing'] as const; | ||
|
|
||
| export const homePrompts: Prompt[] = homePromptIds.map((id) => { | ||
| const found = prompts.find((prompt) => prompt.id === id); | ||
| if (!found) { | ||
| throw new Error(`homePromptIds references unknown prompt id: ${id}`); | ||
| } | ||
| return found; | ||
| }); | ||
|
|
||
| export type PromptGroup = { | ||
| category: PromptCategory; | ||
| eyebrow: string; | ||
| heading: string; | ||
| }; | ||
|
|
||
| /** Display order of categories on /prompts. */ | ||
| export const promptGroups: PromptGroup[] = [ | ||
| {category: 'get-started', eyebrow: 'Get started', heading: 'Spin up React on Rails.'}, | ||
| { | ||
| category: 'server-rendering', | ||
| eyebrow: 'Server rendering', | ||
| heading: 'Render on the server: RSC, SSR, streaming.', | ||
| }, | ||
| {category: 'migrate', eyebrow: 'Migrate', heading: 'Move an existing setup to React on Rails.'}, | ||
| {category: 'features', eyebrow: 'Build features', heading: 'Add common capabilities.'}, | ||
| { | ||
| category: 'production', | ||
| eyebrow: 'Optimize & go to production', | ||
| heading: 'Tune performance and ship with Pro.', | ||
| }, | ||
| ]; |
There was a problem hiding this comment.
Add missing newline at end of file.
As per coding guidelines, all files must end with a newline. The file currently ends at line 167 without a trailing newline.
🤖 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 `@prototypes/docusaurus/src/constants/prompts.ts` around lines 1 - 167, The
file is missing a trailing newline; add a single newline character at EOF so the
file ends with a newline (ensure the last line after the export const
promptGroups block ends with a newline). Locate the file by symbols such as
SITE_URL, prompts, homePrompts, or promptGroups and append the newline to
satisfy coding guidelines.
Source: Coding guidelines
…ck-start-prompts * origin/main: Normalize UI label capitalization to sentence case (#123) Restore footer consultation link (revert footer dedupe) Revise CTA consistency: keep intentional labels/destinations, dedupe footer Unify demo naming, live demo URL, and consultation CTA on marketing pages Point Gumroad demo at gumroad.reactonrails.com and add screenshot Point Octochangelog demo at changelog.reactonrails.com and add screenshot Show HiChee as a live React on Rails example # Conflicts: # prototypes/docusaurus/src/pages/index.tsx
|
Cloudflare preview deployed.
|


Summary
/promptspage: a browsable prompt library grouped by intent (Get started, Server rendering, Migrate, Build features, Optimize & go to production), linked from the home Quick Start via "Browse all prompts →" and from the navbar.What changed
src/constants/prompts.ts— new data module: 11 prompts (confirmed doc URLs only), the RSC-first home subset, and the page category groups.src/components/PromptCard/— new reusable card (title, prompt text, copy-to-clipboard, "Open guide →"), mirroringDemoCard.src/pages/prompts.tsx+prompts.module.css— the/promptspage, mirroringexamples.tsx.src/pages/index.tsx+index.module.css— home Quick Start refactor; removed CSS this orphaned (.inlineCode,.quickStartCardselectors).docusaurus.config.ts— navbar "Prompts" link.Visual changes (before / after)
Verification
npm --prefix prototypes/docusaurus run typecheck→ passes.npm run build:full→ succeeds;/promptsgenerated; all 11 prompt guide links resolve. CIbuild+deployare green. The broken-link warnings in the build are pre-existing docs-content issues, not from these pages./promptsrender, all three home cards present (RSC first), no console errors.AGENTS.md.Notes
prompts.tsonce their doc URLs are verified.slug: existing-rails-appfront-matter in upstreaminstallation-into-an-existing-rails-app.md; if that slug is removed upstream, that card's link breaks.main(sentence-case label normalization Normalize UI label capitalization to sentence case #123 + CTA changes); the only conflict was the deletedquickStartCardsarray — resolved by keeping the deletion. All of main's sentence-case labels are preserved.Spec:
docs/superpowers/specs/2026-06-04-home-quick-start-prompts-design.md· Plan:docs/superpowers/plans/2026-06-04-home-quick-start-prompts.md🤖 Generated with Claude Code