Caddi
Sign inSign up

Install Pinpoints

One script. Async-loaded. About 9kB gzipped. Templates ship with this already wired.

The snippet

html
<script
  src="https://pinpoints.caddi.build/v1.js"
  data-caddi-project="proj_01H9X4..."
  async
></script>

You can get the data-caddi-project value from the project page in the dashboard or with caddi project info --json.

Next.js (app router)

tsx
// app/layout.tsx
import Script from 'next/script';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html>
      <body>
        {children}
        {process.env.NEXT_PUBLIC_CADDI_PINPOINTS === 'on' && (
          <Script
            src="https://pinpoints.caddi.build/v1.js"
            data-caddi-project={process.env.NEXT_PUBLIC_CADDI_PROJECT_ID}
            strategy="afterInteractive"
          />
        )}
      </body>
    </html>
  );
}

Astro

astro
---
const ON = import.meta.env.PUBLIC_CADDI_PINPOINTS === 'on';
const PROJECT = import.meta.env.PUBLIC_CADDI_PROJECT_ID;
---
<html>
  <body>
    <slot />
    {ON && (
      <script
        is:inline
        src="https://pinpoints.caddi.build/v1.js"
        data-caddi-project={PROJECT}
        async
      />
    )}
  </body>
</html>
We strongly recommend gating the script on an env var so production stays clean. See Per-env toggle.

Triggering

  • Default keybind: Cmd+Shift+P (or Ctrl+Shift+P on Windows/Linux).
  • Or call window.Caddi.pinpoints.open() from your own button.

What clients see

Nothing, until they hit the keybind. Then a slim floating bar appears in the top-right asking them to click an element and write a note. Submit closes it. No FAB, no widget intrusion.

Next

Per-env toggle →