Broken Here

Connecting Linear

One button and a team, or a personal API key.

Reports become Linear issues with one click.

Connect Linear

On the project's Settings › Trackers, press Connect Linear on the Linear row. Linear asks you to allow Broken Here to read your teams and open issues; allow it, and you come back to pick the Default team. Nothing to copy, and nothing we store can do more than that.

The key below is still accepted, under Use an API key instead, for a workspace that does not allow outside apps.

Create a key

In Linear, open Settings → Security & access → API keys → New API key. Copy the key; it starts with lin_api_.

A personal key can see everything you can, and Linear has no per-team key. Reports go to the team you pick below, but the key can still reach every team you can. If that matters more than convenience, make the key on a service account that is only in the teams it needs.

Connect it

In the project's Settings › Trackers, on the Linear row (Setup's Send reports to a tracker step links there too):

  • API key: paste it once. We ask Linear whether it accepts the key before storing anything. A key it refuses is not saved, and a key already saved stays in use. If Linear cannot be reached, the key is saved and the row says it was not checked. It is stored encrypted and never shown again; paste a new one to replace it.
  • Default team: a dropdown of the teams the key can see. Reports open as issues in the one you pick.

What lands in the issue

The issue title is the report's summary. The description opens with the reporter's own words, because that is what a developer reads, followed by these sections, each only when there is something to show:

  • Where: the URL, the element selector, the element's text
  • Environment: browser, OS, viewport, pixel ratio, language, time
  • JavaScript errors: with timestamps
  • Failed requests: status, method, URL, duration
  • Console: warnings and errors only
  • Screenshots: the reported element outlined in red

Linear renders markdown, so the issue gets the same body as a Notion page. Screenshots link through Broken Here instead of to signed storage URLs, so the links do not expire.

The issue ends with a link back to the full report.

After it is sent

The report links straight to the issue, and its status moves from Reported to Confirmed on its own, since someone has now looked at it.

A report makes one ticket per tracker, and each connected tracker has its own Send instantly switch on its row under Trackers. The first one you connect has it on and any later one starts with it off, so connecting a second never doubles every ticket. With none on, nothing is sent until someone presses Send in the inbox.

Adding to an issue that already exists

This does not work for Linear yet. Pasting a Notion URL into Add to an existing ticket adds the report to that page. A Linear URL does not, because it carries the issue's identifier (ENG-123) and the API wants the issue's id. The report keeps the link and opens a new issue in the default team, as any unrecognised link does.

Testing it without a workspace

pnpm fake-linear stands in for the API on port 8902, and LINEAR_API_URL=http://localhost:8902 pnpm dev points the app at it. It offers two teams, refuses the key bad (and bad400 with a 400, as the real API does), answers down with a 503, and refuses a key sent with a Bearer prefix, which the real API also does to a personal key.

On this page