Fix RSC build error: pass rendered icon element to DocArticle

DocArticle is a client component, so passing a Lucide icon *component
type* (a function) from the server-rendered doc pages tripped the RSC
"Functions cannot be passed directly to Client Components" check during
prerender of /docs/*. Switch the `icon` prop to React.ReactNode and pass
already-rendered <Icon /> elements from each doc page.

Made-with: Cursor
This commit is contained in:
Randall Stillwell 2026-04-24 15:17:55 -05:00
parent 3a75bfa7de
commit 532a818995
7 changed files with 17 additions and 11 deletions

View file

@ -14,7 +14,7 @@ export default function FaqPage() {
<DocArticle <DocArticle
title="Frequently Asked Questions" title="Frequently Asked Questions"
description="Quick answers to what comes up most often." description="Quick answers to what comes up most often."
icon={HelpCircle} icon={<HelpCircle className="size-[18px]" />}
> >
<DocSection title="How accurate is the OCR?"> <DocSection title="How accurate is the OCR?">
<p> <p>

View file

@ -17,7 +17,7 @@ export default function FormsTemplatesPage() {
<DocArticle <DocArticle
title="Forms &amp; Templates" title="Forms &amp; Templates"
description="Define what fields Echo should pull from each card, map them to your data model, and validate before going live." description="Define what fields Echo should pull from each card, map them to your data model, and validate before going live."
icon={FileText} icon={<FileText className="size-[18px]" />}
> >
<DocSection title="What is a form template?"> <DocSection title="What is a form template?">
<p> <p>

View file

@ -17,7 +17,7 @@ export default function GettingStartedPage() {
<DocArticle <DocArticle
title="Getting Started" title="Getting Started"
description="Go from signup to your first processed response card in about 10 minutes." description="Go from signup to your first processed response card in about 10 minutes."
icon={Rocket} icon={<Rocket className="size-[18px]" />}
> >
<DocSection title="1. Create your account"> <DocSection title="1. Create your account">
<DocSteps> <DocSteps>

View file

@ -17,7 +17,7 @@ export default function ReportsExportsPage() {
<DocArticle <DocArticle
title="Reports &amp; Exports" title="Reports &amp; Exports"
description="Slice your card data, export CSVs, and push the results to your connected tools." description="Slice your card data, export CSVs, and push the results to your connected tools."
icon={BarChart3} icon={<BarChart3 className="size-[18px]" />}
> >
<DocSection title="Built-in reports"> <DocSection title="Built-in reports">
<p> <p>

View file

@ -15,7 +15,7 @@ export default function TroubleshootingPage() {
<DocArticle <DocArticle
title="Troubleshooting" title="Troubleshooting"
description="Common problems, quick fixes, and how to get unstuck." description="Common problems, quick fixes, and how to get unstuck."
icon={Wrench} icon={<Wrench className="size-[18px]" />}
> >
<DocSection title="OCR accuracy is lower than I expected"> <DocSection title="OCR accuracy is lower than I expected">
<ul className="ml-6 list-disc space-y-2"> <ul className="ml-6 list-disc space-y-2">

View file

@ -17,7 +17,7 @@ export default function UploadingCardsPage() {
<DocArticle <DocArticle
title="Uploading Cards" title="Uploading Cards"
description="Everything about getting response cards into Echo — manual uploads, email ingestion, FTP watchers, and the OCR processing lifecycle." description="Everything about getting response cards into Echo — manual uploads, email ingestion, FTP watchers, and the OCR processing lifecycle."
icon={Upload} icon={<Upload className="size-[18px]" />}
> >
<DocSection title="Supported file types"> <DocSection title="Supported file types">
<ul className="ml-6 list-disc space-y-1"> <ul className="ml-6 list-disc space-y-1">

View file

@ -1,7 +1,7 @@
"use client"; "use client";
import Link from "next/link"; import Link from "next/link";
import { ArrowLeft, type LucideIcon } from "lucide-react"; import { ArrowLeft } from "lucide-react";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card"; import { Card, CardContent } from "@/components/ui/card";
import { openContactSupport } from "@/components/support/contact-support-dialog"; import { openContactSupport } from "@/components/support/contact-support-dialog";
@ -9,14 +9,20 @@ import { openContactSupport } from "@/components/support/contact-support-dialog"
interface DocArticleProps { interface DocArticleProps {
title: string; title: string;
description?: string; description?: string;
icon?: LucideIcon; /**
* Icon element, e.g. <Rocket className="size-[18px]" />. Passed as a
* rendered React element rather than a component type so server-rendered
* doc pages can pass it to this client component without tripping the
* "functions cannot be passed to client components" RSC check.
*/
icon?: React.ReactNode;
children: React.ReactNode; children: React.ReactNode;
} }
export function DocArticle({ export function DocArticle({
title, title,
description, description,
icon: Icon, icon,
children, children,
}: DocArticleProps) { }: DocArticleProps) {
return ( return (
@ -30,9 +36,9 @@ export function DocArticle({
All docs All docs
</Link> </Link>
<div className="flex items-start gap-3"> <div className="flex items-start gap-3">
{Icon && ( {icon && (
<div className="mt-1 flex size-9 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary"> <div className="mt-1 flex size-9 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary">
<Icon className="size-[18px]" /> {icon}
</div> </div>
)} )}
<div> <div>