Docs

Getting started

Install with Nuxt

Passback adds a small button to your site while you develop. Click it, click anything on the page, and write what should change. The comment goes to the coding agent you already have open.

Before you start

  • A Nuxt 4 project.
  • Node 22 or later.
  • One of Claude Code, Codex or Cursor, opened in the project.

Install

  1. In your project folder, add the two packages:

    npm i -D passback @passback/vite-plugin
  2. Set the project up:

    npx passback init --apply
    • Init does: detects that this is a Nuxt project, safely edits a recognised Vite config to add the plugin, and prints the Nuxt head instructions below. It installs no packages and never edits your layout.
    • You do: open app/app.vue, apply the printed instructions to its setup script while keeping everything it already has, and restart your dev server.
    .: manually edit app/app.vue; pages show the widget only after this helper call.
    .: import { passbackHead } from '@passback/vite-plugin/head' in <script setup>; add const tags = passbackHead(); useHead({ script: tags.filter(t => t.tag === 'script').map(t => ({ ...t.attrs, ...(t.children === undefined ? {} : { innerHTML: t.children }) })), meta: tags.filter(t => t.tag === 'meta').map(t => t.attrs) });
  3. Add the plugin to nuxt.config.ts yourself. Init only recognises vite.config files, so it does not edit this file. Put passback() under vite.plugins:

    // nuxt.config.ts
    import passback from '@passback/vite-plugin';
    
    export default defineNuxtConfig({
      vite: {
        plugins: [passback()],
      },
    });

    If your config already has a vite block, add passback() to its plugins list.

  4. Add the helper to your app root, app/app.vue. Merge this into the setup script the file already has, and keep the template and everything else as they are:

    <script setup lang="ts">
    import { passbackHead } from '@passback/vite-plugin/head';
    
    const tags = passbackHead();
    useHead({
      script: tags
        .filter((tag) => tag.tag === 'script')
        .map(({ attrs, children }) => ({
          ...attrs,
          ...(children === undefined ? {} : { innerHTML: children }),
        })),
      meta: tags.filter((tag) => tag.tag === 'meta').map(({ attrs }) => attrs),
    });
    </script>
  5. Start your dev server as usual, or restart it if it was running. The Passback button appears in the bottom right corner.

  6. Restart your agent in the project and approve the passback server when it asks. Then start a session: type /passback in Claude Code or Cursor, $passback in Codex. The agent waits for your first comment.

What a comment carries

  • The element you marked, your note and the page it was on.
  • No Nuxt component names, source files or line numbers.

Compare frameworks in What a comment carries.

Comments from a build

In development a comment goes to the coding agent. In a staging build configured with mode: 'relay', a siteKey, an endpoint and stagingModes, comments go to the hosted relay:

passback({
  mode: 'relay',
  siteKey: '…',
  endpoint: '…',
  stagingModes: ['staging'],
});

Production builds outside stagingModes ship nothing because the helper returns nothing. The tags the helper writes follow the plugin's widget and screenshot settings. For the options, see Install with Vite.

Without the plugin, see Where the tag goes in your framework.

Next: Install with React Router