React pdf kit nextjs app router
Skill react-pdf-kit/agent-skills/skills/react-pdf-kit-nextjs-app-router
Integrate @react-pdf-kit/viewer (>=2.0.0 <3.0.0) into a Next.js 15 App Router project using a 'use client' boundary and dynamic imports with ssr:false for RPConfig and the viewer.From its SKILL.md
npx -y skills add react-pdf-kit/agent-skills --skill react-pdf-kit-nextjs-app-routerAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
4.8 KB, ~1.2k tokens by cl100k_base, as published. Nobody here has run it
react-pdf-kit-nextjs-app-router
Use this skill when: the developer asks to add a PDF viewer using
@react-pdf-kit/viewer to a Next.js App Router project (app/
directory) on Next.js 15+ (with Turbopack). For Pages Router use
react-pdf-kit-nextjs-pages-router. Next.js 14 is not supported by
v2 — see react-pdf-kit-nextjs14-pdfjs-override.
The viewer is client-only: it relies on browser APIs and cannot run on the server. The skill structures the integration around that constraint.
Gotchas
- The viewer cannot render on the server. Importing it into a
Server Component (or letting Next SSR it) throws
TypeError: Promise.withResolve is not a function. Every component that imports from@react-pdf-kit/viewerneeds'use client', AND must be mounted through anext/dynamicimport withssr: false. - Install only
@react-pdf-kit/viewer. Do NOT installpdfjs-distseparately. It is an auto-installed peer dependency. No worker configuration is required either —RPConfighandles it. Custom worker URLs / version overrides live inreact-pdf-kit-worker-config. RPConfigshould be rendered once, at the root layout, so the license and config apply app-wide. The page-level viewer mounts theRPProvider/RPLayout/RPPageschain.- Use Turbopack on Next.js 15 (
next dev --turbopack) for the smoothest experience. Next.js 14 + webpack is unsupported by v2. - Hydration: render the viewer inside a fixed-height container so layout doesn't shift. Without a definite height the virtualizer can mount with 0 rows.
RPDefaultLayoutis deprecated in v2. UseRPLayout.
Procedure
1. Install the library
pnpm add @react-pdf-kit/viewer
2. Put RPConfig at the root layout (client-only)
// app/components/AppProviders.tsx
'use client'
import { RPConfig, type RPConfigProps } from '@react-pdf-kit/viewer'
import { type PropsWithChildren } from 'react'
export default function AppProviders({
children,
...props
}: PropsWithChildren<RPConfigProps>) {
return <RPConfig {...props}>{children}</RPConfig>
}
// app/components/LazyAppProviders.tsx
'use client'
import dynamic from 'next/dynamic'
const LazyAppProviders = dynamic(() => import('./AppProviders'), {
ssr: false,
})
export default LazyAppProviders
// app/layout.tsx
import { type PropsWithChildren } from 'react'
import LazyAppProviders from './components/LazyAppProviders'
export default function RootLayout({ children }: PropsWithChildren) {
return (
<html lang="en">
<body>
<LazyAppProviders licenseKey="your-license-key">
<main>{children}</main>
</LazyAppProviders>
</body>
</html>
)
}
licenseKey is optional; without it the viewer runs in trial mode
(watermark).
3. Create the viewer and its lazy wrapper
// app/components/AppPdfViewer.tsx
'use client'
import { RPProvider, RPLayout, RPPages } from '@react-pdf-kit/viewer'
export default function AppPdfViewer({ pdfSrc }: { pdfSrc: string }) {
return (
<RPProvider src={pdfSrc}>
<RPLayout toolbar>
<RPPages />
</RPLayout>
</RPProvider>
)
}
// app/components/LazyAppPdfViewer.tsx
'use client'
import dynamic from 'next/dynamic'
const LazyAppPdfViewer = dynamic(() => import('./AppPdfViewer'), {
ssr: false,
})
export default LazyAppPdfViewer
4. Use it in a page inside a definite-height container
// app/document/[id]/page.tsx
import LazyAppPdfViewer from '../../components/LazyAppPdfViewer'
export default function DocumentPage({ params }: { params: { id: string } }) {
return (
<main style={{ height: '100vh' }}>
<LazyAppPdfViewer pdfSrc={`/api/documents/${params.id}.pdf`} />
</main>
)
}
Verify
pnpm install
pnpm build
pnpm dev --turbopack # then visit /document/<id>
Open the page. The first PDF page should render with the default
toolbar. Scroll to confirm virtualization, and select text on a
rendered page to confirm the text layer mounted. There should be no
Promise.withResolve is not a function error in the console.
References
- Next.js dynamic import: https://nextjs.org/docs/app/api-reference/functions/dynamic
- Companion skills:
react-pdf-kit-nextjs14-pdfjs-override: read this if the project is on Next.js 14 (v2 is unsupported there).react-pdf-kit-worker-config: for overridingpdfjs-distand the Next.js 15 / TurbopackworkerUrlrecipe.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.