Broken Here

Connecting Notion

Connect with one click, or with an internal integration, and pick the database.

Reports become Notion pages with one click. Press Connect Notion and tick the database, or paste an internal integration's secret. Then pick the default database, whose list we can only fetch once Notion has let us in.

Both ways are on the Notion row of the project's Settings › Trackers, which Setup's Send reports to a tracker step links to. Where that row offers Connect Notion, it is the quicker way. Notion asks which pages to share, you tick the database reports belong in, and you come back to the Notion row, where you choose that database, with nothing to paste. Setup's own Notion button does the same. Otherwise, or under Use an internal integration secret instead on the same row, you paste an internal integration's secret, set up as below.

Create an integration

At notion.so/my-integrations, create an internal integration and copy its Internal Integration Secret. It starts with ntn_ (older ones start with secret_).

Give it the capabilities Insert content and Read content. It does not need to update or delete anything, and it reads only what you share with it in the next step.

Share the database with it

A fresh integration can see nothing. Open the database you want reports in, then ⋯ → Connections → your integration.

A Notion page id says nothing about which database it belongs to, so what you share with the integration is the only boundary on what it can reach. Share the database reports belong in, and nothing else.

Connect it

In the project's Settings › Trackers, on the Notion row:

  • Internal integration secret (under Use an internal integration secret instead when the row offers Connect Notion): paste it. We ask Notion whether it accepts the secret before storing anything. A secret it refuses is not saved, and one already saved stays in use. If Notion cannot be reached, the secret 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 database: a dropdown, filled from whatever you shared in the step above. An empty list means the sharing step has not happened yet.

What lands on the page

The page title is the report's summary. The body opens with the reporter's description, 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

A page in a bad way can produce thousands of console lines and hundreds of failed requests. The Notion page lists the first ten of each and says how many were left out. The full report, linked at the bottom, has everything that was captured.

Every Notion database has exactly one title property, but its name is whatever your workspace called it: Name, Bug, Titre. We look it up rather than guess, because a wrong guess makes Notion reject the whole page.

Notion accepts at most 100 blocks when a page is created, so a very long report is cut there, but the link back to the full report always stays.

Adding to a page that already exists

If a reporter pastes a Notion URL into Add to an existing ticket, the report is appended to that page as new blocks, and no new page is created. Someone who links a page is saying this belongs there.

The page has to be one the integration can see. If it is not, the report becomes a new page in your database instead, with the link on it. When Send instantly is off and the link was the only reason to send, nothing is created. The report says Notion cannot see the page, and pressing Send files it as a new page.

The field is team-only and appears only on a project marked as internal. A client-facing project never shows it, and the server drops it if it is posted anyway.

After it is sent

The report links straight to the page, 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 tracker has its own Send instantly switch on its row under Trackers. The first tracker you connect has it on and any later one starts with it off, so a second tracker never doubles every ticket the day it is connected. With none on, nothing is sent until someone presses Send in the inbox.

Either way, Broken Here keeps the report. Its inbox entry, the captured context and the reporter's status link exist whether or not anything reached Notion.

Testing it without a workspace

pnpm fake-notion stands in for the API on port 8901, and NOTION_API_URL=http://localhost:8901 pnpm dev points the app at it. It offers two databases, names its title property in French so that hardcoding Name fails loudly, rejects the secret bad with a 401 so the error path can be seen, and answers down with a 503, like a Notion that cannot be reached.

On this page