Deploying
Build the deck, put it on Vercel or any Node host, set the public site URL, share a link to one slide, and decide who can reach the presenter window.
A deck is a Next.js app, so deploying it is deploying a Next.js app. This page covers the parts that are about the deck rather than about Next.
Build it
npm run build
That is next build, the script deckard init wrote. Every slide prerenders to static HTML, because the slide route reads nothing from the request.
Check the deck before you build, not after:
deckard validate
deckard check-overflow
A duplicate slug fails the build with a message naming both slides. Troubleshooting has that one and the rest.
Vercel
Import the repository and deploy. A deck generated by deckard init sits at the repository root with its own package.json, so Vercel detects Next.js and needs no build settings.
If the deck lives inside a monorepo, set the project’s root directory to the deck’s folder and let Vercel infer the rest.
Any Node host
next build then next start, behind whatever process manager the host uses. The default port is 3000 and next start -p <n> moves it.
The deck needs a Node runtime for next start even though every slide is static. If the host only serves files, use static export instead, which needs two changes to the app.
The public site URL
app/sitemap.ts builds absolute URLs, and it needs to know the deck’s address:
NEXT_PUBLIC_SITE_URL=https://talk.example.com
Without it the sitemap falls back to http://localhost:3000 and publishes localhost URLs. Pass siteUrl to the adapter instead if you would rather keep it in the file:
export default createDeckSitemap(deck, { siteUrl: "https://talk.example.com" })
The variable is NEXT_PUBLIC_, so Next inlines it at build time. Setting it after a deploy changes nothing until the next build.
That sitemap is also how deckard screenshots, check-overflow, and export pdf find the slide list, so keep the route even if you do not care about search engines.
A custom domain
Point the domain at the deployment, then set NEXT_PUBLIC_SITE_URL to the final address and rebuild. Nothing else in the deck holds a hostname.
Sharing one slide
Give the slide a slug and link to /slides/<slug>.
{ slug: "pricing", title: "Pricing", body: <PricingSlide /> }
A slide with no slug is served at its 1-based position, so it is /slides/4 until someone inserts a slide above it and it becomes /slides/5. A slug is the link that survives reordering. Writing slides covers the rules; slugs take lowercase letters, digits, and hyphens.
/ redirects to the first slide, so the bare domain is a fine thing to hand out.
Speaker notes are public
notes never render in the deck, and they do ship to the browser with the slide. They are in the prerendered HTML, so anyone who can open a slide can read them in the page source.
Write notes on the assumption that the audience can read them, or keep the deployment private until after the talk.
The presenter window
/presenter is an ordinary static route and deploys with the deck. Anyone who has the URL can open it.
On its own it shows nothing. The two windows sync over a BroadcastChannel, which is same-origin and same-browser, so a stranger loading /presenter gets an empty console reading Waiting for connection from the slideshow tab. It never reaches your machine and never pulls your notes across the network.
The exposure that matters is the one above: the notes are in the slide page, not in the presenter route. Blocking /presenter does not hide them.
If you want the whole deck private, put the deployment behind the host’s access control. On Vercel that is deployment protection on the project.
Fonts and assets
Files in public/ are served from the site root, so public/logo.svg is /logo.svg. Reference them with a root-relative path; the deck holds no base path.
A built-in theme reaches no font host. The ones set in a real typeface ship it inside @thebuilder/deckard-themes, subset and self-hosted, and the rest use system stacks. Adding a web font of your own is next/font in app/layout.tsx, the same as any Next app.
Images in the media blocks go through next/image, which needs the optimizer the host runs. That is automatic on Vercel and on any Node host running next start. It is the one thing static export has to turn off.
What deploys and what does not
| Route | Deployed | Notes |
|---|---|---|
/ |
yes | Redirects to the first slide. |
/slides/<id> |
yes | One static page per slide, notes included. |
/presenter |
yes | Empty until a deck window on the same origin syncs to it. |
/sitemap.xml |
yes | Absolute URLs from NEXT_PUBLIC_SITE_URL. |
The deck controls, the command center, and the presenter popout are client-side and need no server of their own.
Handing out a PDF instead
deckard export pdf writes out/slides.pdf, one page per slide, and needs no hosting at all. Read Exporting for the flags, and Accessibility for what a PDF loses compared to the deployed deck.