Norg heading metadata: a practical boundary for structured facts
Norg can carry document-wide and section-specific facts as metadata. Here is a worked example, a clear sidecar trade-off, and parser checks to verify the result.
25 Sept 2025, 18:42 UTC

A Norg note often mixes durable structure with transient facts: a heading says “Verify artifacts,” while the prose explains who owns it and whether it is done. That is readable, but difficult for a script to process reliably. The useful boundary is to put file-wide facts in document metadata, section-specific facts in heading metadata, and use a separate structured file only when another system needs a typed schema.
Use two metadata scopes
Norg headings encode nesting with asterisks: one asterisk starts a top-level heading, and additional asterisks create deeper levels. Metadata adds a second dimension. A document metadata block describes the file as a whole. A heading metadata block, placed immediately after a heading, describes that heading.
This article assumes your implementation supports the conventional @document.meta and @metadata blocks. Confirm that assumption against the stable reference documentation for the exact parser you use before adopting the pattern.
@document.meta
title: Release checklist
description: Checks required before publishing the release
@end
* Prepare release
@metadata
owner: release-team
status: pending
@end
** Verify artifacts
@metadata
owner: ci
status: pending
@end
The scope is now explicit. The title and description belong to the document. The owner and status under “Prepare release” belong only to that section. The values under “Verify artifacts” remain separate even though the second heading is nested inside the first.
That distinction matters when an indexer, task generator, or validation script reads the file. Without it, a tool must infer ownership from surrounding paragraphs or assume that every metadata block applies to the entire document.
Choose metadata or a sidecar deliberately
Heading metadata is a good fit when the data is meaningful only within the note and the consuming tool already understands Norg. It keeps the fact beside the section it describes and avoids maintaining two files that can drift apart.
A sidecar file, such as JSON or YAML, is usually better when several non-Norg systems must consume the same data, when the values need a formal schema, or when a central database owns their lifecycle. A sidecar also avoids depending on a parser to expose metadata through an application programming interface.
| Requirement | Better representation | Reason |
|---|---|---|
| One title for the whole note | Document metadata | Its scope is unambiguous |
| An owner for one section | Heading metadata | The fact stays with its section |
| Validation against a shared schema | Sidecar file | External tools can validate it directly |
| Data shared across many notes | Database or sidecar | The note should not become the source of truth |
Treat metadata as untyped data
Metadata syntax does not make the values trustworthy. In the example, status: pending is text, not an enforced enumeration. A script that consumes it should still reject unknown statuses, missing owners, or inconsistent values.
Also avoid assuming that metadata will be visible in the rendered page. A parser may retain it in its abstract syntax tree—the structured representation produced by parsing—without displaying it. If people need to see the status, include a concise visible summary as well; if machines are the only consumers, avoid duplicating the value in prose.
Do not put credentials, tokens, or other secrets in metadata. Norg files are commonly committed to version control, and metadata may be indexed or exposed by publishing tools even when it is not rendered.
Verify attachment, not just syntax
Save the example as metadata-example.norg in a scratch directory. From that directory, run the parse or check command documented by your installed Norg implementation. Do not assume a generic command such as norg --check exists: the executable and flags vary by implementation. No elevated permissions or network access should be needed for a local parse.
Check four results:
- The parser reports no syntax error.
- Document metadata is exposed separately from heading metadata.
- Each
ownerandstatusvalue is attached to the intended heading. - Rendering preserves the heading hierarchy and does not silently discard metadata.
Then test a malformed copy with a missing @end terminator. The parser should report the problem rather than silently absorbing later content. If you also run a formatter, do it on a copy first: a formatter that does not understand your metadata implementation could remove or relocate it.
A practical adoption rule
Use heading metadata for facts that belong to one section and will be read through the same Norg toolchain. Use document metadata for file-wide identity. Move the data to a sidecar when independent validation, cross-tool sharing, or a stronger lifecycle guarantee becomes more important than keeping the fact beside the prose.
Before rolling the pattern out, record the parser version, confirm the two metadata forms in its reference documentation, and add the four checks above to your test suite. That turns a convenient convention into an engineering guarantee your notes can rely on.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.