LinkDen
Getting Started

Configuration

Set up environment variables and authentication for your LinkDen instance.

⚙️ Configuration

LinkDen keeps its .env file minimal on purpose. You only need five environment variables to get running. Everything else -- email, CAPTCHA, branding, and more -- is configured through the admin panel and stored in the database.

⚡ TL;DR

  • Required: 5 variables (BETTER_AUTH_SECRET, BETTER_AUTH_URL, CORS_ORIGIN, NEXT_PUBLIC_SERVER_URL, NEXT_PUBLIC_SITE_URL).
  • Config Location: Most settings are in /admin/settings (DB), not .env.
  • Auth: Built-in email/password (Better Auth). No external provider needed.

1. 🔑 Environment Variables

Create your .env file from the example:

cp .env.example .env

Required Variables Checklist

  • BETTER_AUTH_SECRET - Private. Signs session cookies.
  • BETTER_AUTH_URL - Public. URL where the API server runs.
  • CORS_ORIGIN - Public. URL where the web frontend runs.
  • NEXT_PUBLIC_SERVER_URL - Public. Same as BETTER_AUTH_URL.
  • NEXT_PUBLIC_SITE_URL - Public. URL of the site itself (used for robots.txt, sitemap.xml, and Open Graph links).

Generating a Secret

Run this to generate a strong, random secret:

openssl rand -base64 32

Paste the output as your BETTER_AUTH_SECRET. Use a different secret for production. Outside localhost the secret must be at least 32 characters and not a placeholder: with a weak or empty secret, sign-in and the admin API answer 503, and bun ship refuses to deploy.


2. 📝 Examples

💻 Local Development

BETTER_AUTH_SECRET=your-generated-secret
BETTER_AUTH_URL=http://localhost:3000
CORS_ORIGIN=http://localhost:3001
NEXT_PUBLIC_SERVER_URL=http://localhost:3000
NEXT_PUBLIC_SITE_URL=http://localhost:3001

🌍 Production

SITE_DOMAIN=links.yourdomain.com
BETTER_AUTH_SECRET=your-production-secret
BETTER_AUTH_URL=https://links.yourdomain.com
CORS_ORIGIN=https://links.yourdomain.com
NEXT_PUBLIC_SERVER_URL=https://links.yourdomain.com
NEXT_PUBLIC_SITE_URL=https://links.yourdomain.com

Tip: In production all four URLs are the same hostname. The web app owns SITE_DOMAIN and the API is routed under it at /api/* and /trpc/*, so there is no separate API domain. Locally the API (:3000) and web app (:3001) are different origins, which is why the local values differ. See Environment Variables for the deploy-only variables.


3. 🔐 Authentication

LinkDen uses email and password authentication, with optional two-factor (TOTP) and magic link sign-in.

  • 🚫 No OAuth needed.
  • 🚫 No external auth service needed.

How it works:

  1. Navigate to /admin/setup.
  2. Create your admin account (enter the Setup token if your deploy sets SETUP_TOKEN).
  3. The first user becomes the admin.
  4. Registration locks automatically.
  5. Sign in at /admin/login. With two-factor on, you are then asked for the 6-digit code from your authenticator app or one of your backup codes.

Two-factor authentication

Turn it on under Settings → Account → Two-factor authentication: scan the QR code (or type the key), enter a code to confirm, and save the backup codes somewhere safe. 2FA only switches on once the first code verifies. You can tick "trust this device for 30 days" at login. Lost both your authenticator and your codes? Run bun reset:password -- --email you@example.com --remote --disable-2fa.

Optional passwordless sign-in under Settings → Account. It can only be turned on once email is configured and while two-factor is off, links expire after 10 minutes, and only your admin address can receive one.

Note: Unauthenticated visitors only see your public link page.


4. 🎛️ Admin Settings (Runtime Config)

Most configuration lives in the admin panel (/admin/design for the page, /admin/settings for account, email, integrations, wallet and data), not in environment variables. This means you can change settings without redeploying:

  • 📧 Email provider -- Resend (Cloudflare Email Workers coming soon), plus where contact-form messages go (Inbox, email, or both).
  • 🛡️ CAPTCHA -- Cloudflare Turnstile, Google reCAPTCHA (v2 checkbox), or hCaptcha on the contact form.
  • 🏷️ Branding -- Whitelabel footer text, link, logo, site name, and admin panel branding.
  • 📇 vCard -- Enable or disable the downloadable contact card.
  • 🍏 Apple Wallet -- Pass design, Team ID, Pass Type ID, signing keys, and custom QR URL.
  • 🔍 SEO -- Page title, meta description, and OG image.
  • 🗺️ MapKit -- Apple Maps token (stored for a planned map embed; Location blocks currently link out to a map).
  • 🍪 Consent Banner -- On by default. Asks visitors before analytics and embedded media load.
  • 🖥️ Admin Branding -- Show or hide LinkDen branding inside the admin panel itself.

Next Steps

On this page