{{/* The status page refreshes itself ONLY while a run is active, and it is a meta refresh because every affordance here works scriptless. This is also the honest mechanism: the import is a goroutine that lives as long as the process, and the platform sleeps an idle app, so an open page is what keeps it awake. The copy below says so rather than implying a background worker memoria does not have. */}} {{define "head"}}{{if .Run}}{{if .Run.Running}}{{end}}{{end}}{{end}} {{define "content"}}

Notion

{{if .Flash}}

{{.Flash}}

{{end}} {{if not .Configured}}

Memoria imports the Notion pages you share with an integration, and everything nested underneath them.

{{/* Info: the untoned callout (runTone says why there is no "info"). */}}

What you connect, Memoria keeps. Once a page is imported, it stays in Memoria and stays readable by everyone here — even if you later archive it in Notion, unshare it, or revoke this token. Removing it is something you do in Memoria.

Connect

  1. In Notion, create an internal integration with read-only capabilities and no user information.
  2. Share the pages you want Memoria to hold with that integration. Sharing a page is what publishes it. Memoria imports what the integration can see and nothing else.
  3. Paste the integration token below.

Checked with Notion before it is saved. It is stored sealed and is never shown again.

{{else}}

Connected

{{if .Verified}}Token last checked {{.Verified}}.{{else}}Token stored.{{end}}

{{if .CountsKnown}}

{{.Imported}} of {{.Pages}} known page{{if ne .Pages 1}}s{{end}} imported.

{{else}}

The page counts could not be read, so this says nothing about how much has been imported.

{{end}}
{{if .Run}}

Last import

{{/* A callout toned by the run's state (spec §4, runTone): a run in progress or finished cleanly is info (untoned), one that finished with pages it could not read, stopped, or failed is a warning. It used to be a plain paragraph, so "some pages could not be read" read like "finished". */}}

{{.Run.Message}}

Started
{{.Run.Started}}
{{if .Run.Finished}}
Finished
{{.Run.Finished}}
{{end}}
Top-level pages shared with the integration
{{.Run.Roots}}
Pages seen
{{if .Run.TotalKnown}} {{.Run.Total}} {{else}} {{.Run.Seen}} so far — the total is not known until the import finishes {{end}}
Imported
{{.Run.Fetched}}
Already up to date
{{.Run.Skipped}}
Empty pages
{{.Run.Empty}}
Could not be read
{{.Run.Failed}} {{if .Run.Failed}}— counted here rather than left out of the totals{{end}}
{{if .Run.Unread}}
Blocks Memoria does not read
{{.Run.Unread}} — a page that came in thin may be one of these
{{end}}
{{end}}

Replace the token

Rotating a token replaces the stored one. The old token is not kept. Nothing already imported is affected.

{{/* Never carries a value. The stored token is not rendered back here or anywhere — not even masked, because a masked secret is still a secret in the DOM. TestTokenIsNeverRendered checks this branch specifically: an earlier version of that gate only looked at the not-yet-connected page, which has no token field at all, so it passed while proving nothing. */}}

Disconnect

This removes the token and stops future imports. It deletes nothing Memoria has already imported — those pages stay here until someone deletes them in Memoria.

{{end}} {{end}}