Foreloop

Install Foreloop

Two things install: the CLI, for driving Foreloop from a terminal or anything that can run one, and the feedback widget, for collecting feedback from inside your own product. They are independent — install either, or both.

The CLI

Projects, loops, intentions, stories and tasks from a terminal — and from anything that can run one, including coding agents and cron.

npm i -g foreloop

npx foreloop … works without installing, but a global install is the recommendation: this is a tool you reach for many times a day, and npx re-resolves the package on every invocation.

Authenticate

Create a key in Settings → API keys (sign-in required). The CLI purpose reaches as far as you do in the web app — it claims and runs work, approves contracts and ships releases — so it belongs in your shell and nowhere else: never in browser code, never in a repository.

foreloop auth login              # the prompt hides the input
foreloop init                    # install the task-executor skill in this repo
foreloop tasks ready             # open tasks whose contract is approved

Run foreloop --help for the common path and the output conventions, and foreloop <group> --help to list a group's commands — everyday ones first, one-off maintenance after.

Built for scripts and agents

  • --json works on any command and has a stable shape. Additive changes only.
  • Exit codes are meaningful: 0 ok, 1 failed, 2 auth, 3 usage, 4 confirmation required. A query that finds nothing still exits 0, so callers branch on the payload rather than on failure:
    foreloop tasks ready --json | jq -e '.tasks | length > 0' && run-my-agent
  • Unknown commands and flags fail outright rather than guessing at intent.
  • FORELOOP_TOKEN outranks any stored credential, so CI needs no login step. FORELOOP_BASE_URL points the CLI at a non-production API.

The package re-exports @foreloop/feedback in full, so one dependency covers both the CLI and the widget below. Embedding the widget and nothing else? @foreloop/feedback alone is smaller and also ships the built browser asset.

The feedback widget

The widget lets people send feedback, bugs, and ideas from inside your product — annotated, screenshotted, and routed into your Foreloop organization as signals. One install covers every route, and each submission carries its own page URL.

1. Get a write-only key

Keys are generated in Foreloop: Widget → Installation (sign-in required). A widget key carries only the signal:write scope — it can submit feedback and nothing else, which is why it may live in browser code and in your repository. Never embed a key with broader scopes.

The key is also what decides where submissions land: they arrive in the organization the key belongs to — yours — whoever sent them. Mint your own rather than reusing one from elsewhere, and the widget needs no endpoint configured, because it posts to https://foreloop.com on its own.

Every snippet below shows flpk_YOUR_WRITE_ONLY_KEY where your key belongs. The in-app page hands you the same snippets with the key already in them.

2. Pick an install path

The same widget with the same options either way — the two differ only in how its code reaches the page.

Hosted

One tag, and we serve the widget. Right for most web projects — Webflow, Framer, WordPress, or any hand-written HTML. Nothing to build, and published fixes reach your site without you redeploying.

Installed

A package in your bundle, for teams building a full app. Costs you a build step and buys flexibility: pass the signed-in user, re-initialize when they change, and serve the asset yourself.

Hosted — one tag

  1. Paste this into the one layout template every page shares, immediately before the closing </body> tag — the same place you would put Google Analytics or any other analytics script.
    <script
      src="https://cdn.jsdelivr.net/npm/@foreloop/feedback@latest/dist/foreloop-feedback.js"
      data-api-key="flpk_YOUR_WRITE_ONLY_KEY"
      async
    ></script>
    On Webflow, Framer, Squarespace and the like, that is the site-wide custom code field for the end of <body> — not the per-page one. Keep async: the widget waits for the DOM itself.
  2. Reload your site. A launcher appears in the lower-right corner. Paste the tag in one place only.

Installed — the npm package

  1. Run this in your project root.
    cd path/to/your-app
    npm install @foreloop/feedback
  2. Paste this into your root layout — the one file that wraps every page (app/layout.tsx in Next.js, App.tsx in Vite).
    import { initForeloopFeedback } from "@foreloop/feedback";
    
    await initForeloopFeedback({
      apiKey: "flpk_YOUR_WRITE_ONLY_KEY",
      reporterName: signedInUser?.email,
    });
    It has to run in the browser only: the initializer touches document and throws during server-side rendering, so in Next.js it needs a "use client" boundary. Call it after the signed-in user is known, and swap signedInUser?.email for your own accessor — omit it for anonymous visitors and the widget asks instead.
  3. Reload your app. A launcher appears in the lower-right corner. The package fetches the widget asset at runtime rather than bundling it, so this path still makes one CDN request.

Options

Each option is a snippet attribute on the hosted path and an initializer property on the installed one.

  • data-api-key / apiKey — the write-only key. Required.
  • data-project / project — the project submissions target. Omit for the organization default.
  • data-trigger / trigger — a CSS selector for elements of yours. Clicks on any match open the widget, and the floating launcher gives way to a centered modal. Omit it for the launcher.
  • data-reporter-name / reporterName — pre-fills the Email field. Omit for anonymous visitors; the widget never infers identity.
  • data-button-label / buttonLabel and data-button-color / buttonColor — the launcher's wording and fill. Use the dark and light variants when one colour cannot serve both pages.
  • captureScreenshot — offers optional screen capture. The browser always asks the user what to share.
  • includeUrlEvidence / includeQuery — attach the page URL. Query strings and fragments stay excluded unless you opt in, because they carry tokens and search terms more often than useful context.
  • data-private / data-sensitive — put these on your own elements to mark what can never be selected as an annotation. Inputs are always excluded.

Content-Security-Policy

If your site enforces a CSP, the widget needs four directives:

  • script-src https://cdn.jsdelivr.net — loads the widget asset, on both paths, because the initializer injects a script tag too. Use 'self' when you serve the asset yourself.
  • connect-src https://foreloop.com — submissions are a fetch to the Foreloop API.
  • style-src — a nonce, or 'unsafe-inline'. The widget injects one <style> element; prefer passing a nonce through data-style-nonce.
  • img-src data: — the screenshot preview renders as a data URL.