---
title: "Templates & examples"
description: "Create an app from the starter template, the playground or the advanced example with create nuxt, run one in StackBlitz, and try unreleased builds from pkg.pr.new."
canonical_url: "https://nuxt-backend.dev/docs/start/templates"
---
# Templates & examples

> Create an app from the starter template, the playground or the advanced example with create nuxt, run one in StackBlitz, and try unreleased builds from pkg.pr.new.

Ready-made apps you create with Nuxt's own `create nuxt` command. Each one is a standalone app of the published package, with plain version ranges and no lockfile, so what you get is exactly what installs from npm. All of them run against a Convex deployment of your own.

<note>

Until `0.2.0` is published, `nuxt-backend: latest` resolves to `0.1.0`, a throwaway test publish. Install a [preview build](#preview-builds-pkgprnew) over it in the meantime.

</note>

## Starter

The app to build on: a Nuxt app with the module installed and nothing else. Every file in `backend/` is byte-identical to what `npx nuxt-backend init` generates, and with zero custom backend code it has:

- passwordless sign-in (`<AuthForm>`, passkeys + email OTP)
- workspaces with emailed invitations (the `/accept-invitation` page is registered by the module)
- transactional, delivery-tracked email under the hood (auth OTP, invitations, gift notifications)
- subscriptions, feature gating, prepaid credits and gifts, once you declare a billing catalog

<code-group>

```bash [pnpm]
pnpm create nuxt@latest my-app -t gh:qruto/nuxt-backend/templates/starter
```

```bash [npm]
npm create nuxt@latest my-app -- -t gh:qruto/nuxt-backend/templates/starter
```

```bash [yarn]
yarn create nuxt my-app -t gh:qruto/nuxt-backend/templates/starter
```

```bash [bun]
bun create nuxt@latest my-app --template=gh:qruto/nuxt-backend/templates/starter
```

</code-group>

`create nuxt` downloads the template, installs it with the package manager you pick, and offers to add more Nuxt modules. Then start it:

```bash
npm run dev   # first run: sets up a Convex dev deployment (log in when asked) and
              # provisions its env; then runs Convex and Nuxt together
```

The `dev` script is [`nuxt-backend dev`](https://nuxt-backend.dev/docs/reference/cli#dev). Then follow the [Quickstart](https://nuxt-backend.dev/docs/start/quickstart#sign-in-with-the-console-otp) from the sign-in step: the OTP prints in the same terminal until you connect an email provider. The scaffolded `billing.catalog.ts` ships with every meter, plan and pack commented out, so `/pricing` has nothing to sell until you fill the catalog and sync it, as in the Quickstart's [billing step](https://nuxt-backend.dev/docs/start/quickstart#declare-a-billing-catalog-and-sync-it).

`backend/_generated` is not part of the template: `npm run dev` writes it against the installed package on the first run, and until then `#backend/*` imports are typed `any`. With pnpm, the template's `.pnpmfile.mjs` answers the build-script question (none of its dependencies needs its script, so none runs) and hoists the component definitions Convex bundles, the same settings [Installation](https://nuxt-backend.dev/docs/start/installation#using-strict-pnpm) gives strict-pnpm users. [View the source](https://github.com/qruto/nuxt-backend/tree/main/templates/starter).

## Example: playground

The [live playground](https://nuxt-backend.dev/playground) as an app of your own: 33 pages that exercise the whole package against your deployment.

<code-group>

```bash [pnpm]
pnpm create nuxt@latest my-playground -t gh:qruto/nuxt-backend/examples/playground
```

```bash [npm]
npm create nuxt@latest my-playground -- -t gh:qruto/nuxt-backend/examples/playground
```

```bash [yarn]
yarn create nuxt my-playground -t gh:qruto/nuxt-backend/examples/playground
```

```bash [bun]
bun create nuxt@latest my-playground --template=gh:qruto/nuxt-backend/examples/playground
```

</code-group>

<table>
<thead>
  <tr>
    <th>
      Group
    </th>
    
    <th>
      Pages
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      Client
    </td>
    
    <td>
      Queries, mutations and actions, pagination, search and counts, file storage, connection state, SSR and preloading, the subscription bridge
    </td>
  </tr>
  
  <tr>
    <td>
      SaaS demo
    </td>
    
    <td>
      The packaged pricing, profile, settings and security pages, styled like the site
    </td>
  </tr>
  
  <tr>
    <td>
      Vanilla
    </td>
    
    <td>
      The same four pages in the package's default look
    </td>
  </tr>
  
  <tr>
    <td>
      Backend platform
    </td>
    
    <td>
      Account, workspaces, roles, billing, feature gates, credits, billing history, metered AI, email, email templates, webhooks, workflows, migrations, rate limiting, aggregates, agents
    </td>
  </tr>
</tbody>
</table>

`npm run dev` starts it like the starter. Until a deployment exists, `/playground` explains how to start one. Accounts are sandbox identities, generated `delivered+…@resend.dev` addresses, as on the live playground. The sign-in code shows up on the login page, with or without an email provider connected. The billing, credits and email pages show empty states until you [connect those services](https://nuxt-backend.dev/docs/reference/cli#env-push).

The app is a copy of the site's playground, not a separate one. Its pages, components and backend are byte-identical to the site's, and the repository's CI fails when the two drift apart. It keeps the site's flat layout (`pages/`, `components/`, `backend/` at the root) and commits `backend/_generated`, because the pages import the generated API. Links into the documentation redirect to this site. [View the source](https://github.com/qruto/nuxt-backend/tree/main/examples/playground).

## Example: advanced

Every customization point at once, created the same way:

<code-group>

```bash [pnpm]
pnpm create nuxt@latest my-app -t gh:qruto/nuxt-backend/examples/advanced
```

```bash [npm]
npm create nuxt@latest my-app -- -t gh:qruto/nuxt-backend/examples/advanced
```

```bash [yarn]
yarn create nuxt my-app -t gh:qruto/nuxt-backend/examples/advanced
```

```bash [bun]
bun create nuxt@latest my-app --template=gh:qruto/nuxt-backend/examples/advanced
```

</code-group>

Start from the starter; each file in `advanced` changes exactly one thing from it:

<table>
<thead>
  <tr>
    <th>
      Customization
    </th>
    
    <th>
      Where
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      Customized app definition — the <code>
        backendEnv
      </code>
      
       contract extended by an extra env var, <code>
        aggregate
      </code>
      
       left unmounted
    </td>
    
    <td>
      <code>
        backend/convex.config.ts
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="https://nuxt-backend.dev/docs/email/templates">
        Custom email templates
      </a>
      
       (OTP, invitation and <a href="https://nuxt-backend.dev/docs/billing/credits/gifts">
        gift
      </a>
      
      ) without replacing the transport
    </td>
    
    <td>
      <code>
        backend/email.ts
      </code>
      
       → <code>
        templates
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      Custom invitation path — emails link to <code>
        /join
      </code>
      
      , where the app's own page replaces the built-in one
    </td>
    
    <td>
      <code>
        backend/auth.ts
      </code>
      
       (<code>
        invitationPath
      </code>
      
      ), <code>
        nuxt.config.ts
      </code>
      
       (<code>
        pages: { acceptInvitation: '/join' }
      </code>
      
      ), <code>
        app/pages/join.vue
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      Explicit billing config instead of env-var defaults
    </td>
    
    <td>
      <code>
        backend/billing.ts
      </code>
      
       (<code>
        accessToken
      </code>
      
       / <code>
        environment
      </code>
      
       / <code>
        webhookSecret
      </code>
      
      )
    </td>
  </tr>
  
  <tr>
    <td>
      Billing webhook hook — <code>
        order.paid
      </code>
      
       writes to an app table, after the built-in refresh + gift fulfilment
    </td>
    
    <td>
      <code>
        backend/billing.ts
      </code>
      
       (<code>
        events
      </code>
      
      ) + <code>
        backend/schema.ts
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      Custom <a href="https://nuxt-backend.dev/docs/ship/production/webhooks#custom-paths">
        webhook paths
      </a>
      
       (<code>
        /hooks/billing
      </code>
      
      , <code>
        /hooks/email
      </code>
      
      )
    </td>
    
    <td>
      <code>
        backend/http.ts
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      Hand-rolled signup workflow — <code>
        workflow.define
      </code>
      
       calling the component's email module directly, instead of <code>
        defineEmailSequence
      </code>
    </td>
    
    <td>
      <code>
        backend/workflows.ts
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      Gift claiming — <code>
        useGifts()
      </code>
      
       + <code>
        <GiftClaimBanner>
      </code>
    </td>
    
    <td>
      <code>
        app/pages/app/index.vue
      </code>
    </td>
  </tr>
</tbody>
</table>

```ts [examples/advanced/nuxt.config.ts]
export default defineNuxtConfig({
  modules: ['nuxt-backend'],
  devtools: { enabled: true },
  css: ['~/assets/main.css'],
  telemetry: false,
  backend: {
    // The invitation page lives at /join, matching
    // `organization.invitationPath` in backend/auth.ts; the app's own page
    // there replaces the built-in one.
    pages: { acceptInvitation: '/join' },
  },
})
```

[View the source](https://github.com/qruto/nuxt-backend/tree/main/examples/advanced).

## Run it in the browser

Open the starter in StackBlitz. The sandbox runs `npm run dev`, which asks you to log in to Convex in its terminal (a device flow) and sets up a dev deployment of your own:

[stackblitz.com/github/qruto/nuxt-backend/tree/main/templates/starter](https://stackblitz.com/github/qruto/nuxt-backend/tree/main/templates/starter)

The playground asks for a Convex development deploy key instead (your project in the dashboard, then Settings, then Deploy keys). Sign-in checks the page origin against `SITE_URL`, so set it to the sandbox's origin with `npx convex env set SITE_URL <origin>` to sign in there:

[stackblitz.com/github/qruto/nuxt-backend/tree/main/examples/playground](https://stackblitz.com/github/qruto/nuxt-backend/tree/main/examples/playground)

## Preview builds (pkg.pr.new)

Every pull request and every commit on `main` publishes a preview of the package through [pkg.pr.new](https://pkg.pr.new), so a fix can be tried before it is released:

```bash
# a specific PR
npm install https://pkg.pr.new/qruto/nuxt-backend@<pr-number>
# a specific commit
npm install https://pkg.pr.new/qruto/nuxt-backend@<commit-sha>
```

The install URL is posted by the pkg.pr.new bot on each PR, next to an **Open in StackBlitz** link that runs the starter with that build wired in. Preview builds carry the exact `exports` map of the release they precede, so the [import tree](https://nuxt-backend.dev/docs/reference/entrypoints) is the same.


## Sitemap

See the full [sitemap](https://nuxt-backend.dev/sitemap.md) for all pages.
