ndk-template-sveltekit-vercel Svelte Themes

Ndk Template Sveltekit Vercel

SvelteKit + Vercel template for building Nostr apps with NDK

SvelteKit + NDK Template

Ship a real Nostr web app without spending your first week rebuilding SSR, auth, SEO, onboarding, and deployment plumbing.

This template gives you the hard parts up front: server-rendered pages that still feel live, session-aware client UX, shareable previews, reusable NDK primitives, and a deployment path that already makes sense.

The included UI uses profiles, notes, articles, comments, and highlights to show the stack in action. Those are examples of what the foundation supports, not the limit of what you can build with it.

What You Get

  • SSR that works for crawlers, links, and real users
  • optional Upstash/Vercel KV-backed NDK cache for SSR event reads
  • live client updates layered on top of server-rendered pages
  • built-in SEO and social previews, including dynamic OG images
  • login flows for common Nostr signer setups
  • onboarding for profiles, interests, and Blossom-backed avatars
  • optional managed NIP-05 registration with username availability checks and .well-known/nostr.json
  • reusable @ndk/svelte primitives already wired into the app structure
  • example app surfaces for profiles, event pages, threaded discussion, and richer content views
  • Vercel-ready deployment without extra platform setup work

Why the split matters

NDKSvelte is the right tool for client subscriptions, live feeds, and session-aware UI. It is not the right thing to depend on for social crawlers. Crawlers only see the HTML returned by the server, so preview-critical routes need to fetch their own Nostr data in +page.server.ts and emit SEO tags there.

This template makes that explicit instead of hiding it behind one cross-environment singleton.

Registry integration

The starter now behaves like a real @ndk/svelte jsrepo consumer:

  • jsrepo.config.ts points at @ndk/svelte
  • registry-installed code lives under src/lib/ndk/*
  • the root layout seeds the shared NDK instance into context for registry components
  • the homepage, profile page, and note/article page already render author UI through the registry-backed ui/user primitive

To add more registry items into the same structure:

bunx jsrepo add ui/user
bunx jsrepo add components/session-switcher

Routes

  • / shows a publication-style front page seeded with long-form articles
  • /profile/[identifier] SSR-fetches an author profile and recent articles
  • /note/[id] SSR-fetches an article or note and author metadata

Both SSR routes return seo data that the root layout renders through SeoHead.svelte.

Local development

bun install
bun run dev

Environment

Set relays with:

PUBLIC_NOSTR_RELAYS=wss://relay.damus.io,wss://purplepag.es,wss://relay.primal.net

If omitted, the template uses those three relays by default.

To let SSR loads serve Nostr events from a durable Vercel-friendly cache, add Upstash Redis REST credentials:

UPSTASH_REDIS_REST_URL=
UPSTASH_REDIS_REST_TOKEN=

Vercel KV's KV_REST_API_URL and KV_REST_API_TOKEN names are also supported. The SSR cache uses @nostr-dev-kit/cache-upstash, stores under the sveltekit-vercel-ndk:ssr:v1 namespace by default, and falls back to relay fetches when the cache is missing or not configured.

Optional cache tuning:

NDK_SSR_CACHE_NAMESPACE=
NDK_SSR_CACHE_TTL_SECONDS=3600

To enable managed NIP-05 registration in onboarding, add:

PUBLIC_NIP05_DOMAIN=your-domain.com

The value can be a bare domain or a full URL. If set, onboarding shows an optional handle field, checks [email protected] availability, and the app serves /.well-known/nostr.json.

For durable registrations on Vercel, also provide a writable KV-compatible store:

KV_REST_API_URL=
KV_REST_API_TOKEN=

Without those two variables, the template falls back to an in-memory registry that is only suitable for local development.

Deploying to Vercel

  1. Import the project into Vercel.
  2. Leave the framework preset on SvelteKit.
  3. Add PUBLIC_NOSTR_RELAYS if you want custom relays.
  4. Add UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN for durable SSR NDK caching. Vercel KV's KV_REST_API_URL and KV_REST_API_TOKEN work too.
  5. Add PUBLIC_NIP05_DOMAIN if you want the template to issue handles for your domain.
  6. Add KV_REST_API_URL and KV_REST_API_TOKEN if you want those handle registrations to persist across instances and did not already add them for SSR caching.
  7. Deploy.

No custom vercel.json is required for the base template.

File map

  • src/lib/ndk/client.ts: browser NDKSvelte instance with session persistence
  • src/lib/ndk/ui/: registry-installed UI primitives from @ndk/svelte
  • src/lib/ndk/builders/: registry-installed builders used by those primitives
  • src/lib/ndk/utils/ndk/: the NDK context helper expected by registry items
  • src/lib/server/nostr.ts: server-only NDK helpers for SSR loads
  • src/lib/seo.ts: preview metadata builders
  • src/lib/components/SeoHead.svelte: canonical, OG, and Twitter tags
  • jsrepo.config.ts: consumer config for adding more registry items with jsrepo

Social preview note

This template ships with a stable default OG image in static/og-default.png plus route-specific titles and descriptions. If you want fully dynamic per-note images, layer that on top of the same SSR metadata flow rather than moving preview generation into client code.

Top categories

Loading Svelte Themes