Troubleshooting
Fix common issues when running the Nuxt template.
Start with the failing boundary: install/build, runtime configuration, database, auth, a provider callback, content, or client rendering. Check the server log and browser console together; Nitro failures often only appear in the terminal.
Install and build
| Symptom | Likely cause | Safe fix |
|---|---|---|
nuxt: command not found | Dependencies were not installed with pnpm | Use Node 22, enable Corepack, then run pnpm install |
Missing .nuxt types/imports | nuxt prepare did not run or generated state is stale | Run pnpm postinstall; if needed remove only generated .nuxt and rerun it |
| Works in dev, fails in build | Server/client boundary, missing runtime env, or content error | Run pnpm eslint . and pnpm build; inspect the first error, not the final cascade |
| Component is unresolved | Wrong auto-import name or directory config | Check components/shadcn in nuxt.config.ts; import explicitly when ownership is unclear |
Do not copy Next.js fixes into this template: there is no App Router,
proxy.ts, next/font, or Next route handler.
PostgreSQL and Drizzle
| Symptom | Inspect | Fix |
|---|---|---|
| Connection refused/auth failed | NUXT_DATABASE_URL, database process, SSL/pooled URL | Test the exact connection string outside Nuxt; use the provider's pooled URL for serverless |
| Relation/table does not exist | server/database/migrations, migration history | Run npx drizzle-kit generate then npx drizzle-kit migrate against the intended database |
| Drizzle cannot find its config | server/database/drizzle/drizzle.config.ts | Pass the config path explicitly if required by your CLI setup and run from the project root |
| Schema change has no effect | Exports from server/database/index.ts | Ensure the changed schema is reachable, regenerate SQL, inspect it, then migrate |
Never run production migrations against a guessed URL. Print the database host (not credentials), back up the database, and review generated SQL first. See Database.
Better Auth and OAuth
Redirect loops, 401 sessions, or bad cookies: verify
NUXT_PUBLIC_BASE_URL exactly matches the browser origin, including protocol
and port. server/utils/auth.ts derives both baseURL and trustedOrigins from
it. Add temporary LAN/dev origins through the comma-separated
NUXT_AUTH_EXTRA_TRUSTED_ORIGINS; do not leave broad production origins.
OAuth callback fails: set both client ID and secret, then register:
<NUXT_PUBLIC_BASE_URL>/api/auth/callback/github
<NUXT_PUBLIC_BASE_URL>/api/auth/callback/googleProvider console URL, public base URL, and the URL in the browser must agree. If credentials are absent, hide the provider button rather than presenting a known-broken path. See Authentication.
Resend email
| Symptom | Check |
|---|---|
| “API key not set” | NUXT_RESEND_API_KEY is server-side and present at runtime |
| Resend rejects sender | websiteConfig.mail.fromEmail uses a verified domain |
| Contact form sends nowhere | websiteConfig.mail.supportEmail is set and monitored |
| Registration cannot complete | Required verification mail must be deliverable |
| Chinese auth email is English | Auth calls currently omit locale; pass it explicitly |
Inspect both application logs and the Resend event dashboard. See Email.
Payments and webhooks
Confirm the exact public routes and methods:
- Creem:
POST /api/payment/notify/creem, raw body,creem-signatureheader,NUXT_CREEM_WEBHOOK_SECRET. - ZPay:
GET /api/payment/notify/zpay, signed query parameters,NUXT_ZPAY_MERCH_KEY.
A 401 from Creem means the signature is missing/invalid; a 500 can mean the
webhook secret is absent. Do not parse and reserialize Creem before verifying
the HMAC. ZPay returns fail when callback verification/handling throws. Also
check the provider-specific notify URL, public HTTPS reachability, product IDs,
and NUXT_CREEM_SERVER_IDX (0 production, 1 test). See
Payments.
AI Gateway and Replicate
| Symptom | Likely cause / fix |
|---|---|
| “Missing AI Gateway API key” | Set server-only NUXT_AI_GATEWAY_API_KEY and restart |
| Model/search selector seems ignored | It is currently UI-only; the server always uses openai/gpt-5.2 |
| AI request returns 401 | Log in or intentionally set NUXT_PUBLIC_AI_PUBLIC_DEMO=true for a demo only |
| Provider “not configured” | Set NUXT_REPLICATE_API_TOKEN; the factory registers Replicate only when present |
| Media polling never finishes | Inspect the Replicate prediction, model input mapping, timeout, and provider status |
| Task succeeds but URL later breaks | Copy output into durable object storage rather than relying on provider URLs |
Model schemas change: re-check input field names whenever replacing a Replicate model. See AI Chat and AI Media.
Nuxt Content and i18n
Page not found: verify the locale collection in content.config.ts, the
file path, required title, and the path built by useDocContent. Chinese docs
and blog collections are configured but currently empty.
Page exists but is missing from docs navigation: update
app/config/docs-sidebar-config.ts; the sidebar is manual.
Wrong language or mixed blog list: prefix_except_default means English is
unprefixed and Chinese uses /zh. Use NuxtLinkLocale/useLocalePath. The
current blog index queries all locale collections, so restrict it to the active
locale when adding Chinese posts.
Draft is visible: published is accepted by the schema but current queries
do not filter it. Add an explicit filter. See Content and
Internationalization.
Theme hydration
If the icon/theme differs between server HTML and hydration, avoid branching on
browser-only storage during SSR. Use useColorMode() and wrap preference-
dependent markup in <ColorScheme>. Keep classSuffix: "", the .dark CSS
variables, and storageKey: "theme" aligned. See Theming.
Docker and Nitro
| Symptom | Check |
|---|---|
| Container starts but cannot be reached | PORT=80, HOST=0.0.0.0, exposed/mapped port |
server/index.mjs missing | Run pnpm build and copy the contents of .output as the Dockerfile does |
| Runtime secrets are undefined | Inject NUXT_* variables into the running container, not only the build stage |
| Uploads vanish after deploy | public/uploads is local and non-durable; move to S3/R2/Blob |
Run the built server with node .output/server/index.mjs locally before
debugging the platform. See Deployment.
Nuxt-specific gotchas
~/@resolve toapp/;~~/@@resolve to the project root;#sharedresolves toshared/.- Server secrets belong directly under
runtimeConfigand useNUXT_*; browser-visible values belong underruntimeConfig.publicand useNUXT_PUBLIC_*. - A variable without the matching Nuxt prefix will not override runtime config.
pathPrefix: falsechanges auto-imported component names; docs components are global, most feature components are not.- A page under
(dashboard)is not protected by its folder. It must declaremiddleware: "auth"(and"admin"where needed), while every API separately enforces auth/role.
Still stuck?
Reduce the failure to one route and record the request method/path, response status, first server stack trace, active runtime (dev/Nitro/Docker), and which required variables are present—never their values. That usually turns a vague “Nuxt is broken” into a pleasantly ordinary bug.
