Repository URL. Setting it enables the edit link; leaving it unset hides the
button. A trailing .git or / is trimmed.
Page Metadata
Under every page OwnDocs renders one small row: the last-updated date pulled
from git log, the people who have touched the file, and an "Edit on GitHub"
button. Scroll to the bottom of this page and you're looking at the live
example.
Quick Start
Nothing to author and nothing to switch on. At build time OwnDocs runs two git
commands against the page's own MDX file, keeps the first five unique authors,
and renders the row.
Last updated
Author date of the newest commit that touched this file, printed as Aug 16, 2026 inside a <time> element.
Contributors
Up to five names, newest commit first, deduplicated by name and by email.
git log -1 --format=%aI -- app/features/platform/page-metadata.mdx
git log --format='%an|%ae' -- app/features/platform/page-metadata.mdxThe first command feeds lastUpdatedIso, the second feeds contributors. When
both come back empty and no edit URL is configured, the whole section returns
null — no empty box, no placeholder text.
Adding Options
Point NEXT_PUBLIC_REPO_URL at your repository and the "Edit on GitHub" button
appears on the right side of the same row.
NEXT_PUBLIC_REPO_URL=https://github.com/your-org/your-repoThat produces
https://github.com/your-org/your-repo/edit/main/app/features/platform/page-metadata.mdx.
The path is the file's location relative to the project root, and the link opens
in a new tab with rel="noopener noreferrer".
Advanced
Docs that live on a release branch need the branch name too, and the URL builder is more forgiving than it looks.
NEXT_PUBLIC_REPO_URL=https://github.com/your-org/your-repo.git/
NEXT_PUBLIC_REPO_BRANCH=developBoth of those extra characters get cleaned up: getEditUrl strips a trailing
.git and a trailing slash from the repo URL and any leading slashes from the
file path before joining them as <repo>/edit/<branch>/<path>. The result is
the same tidy .../edit/develop/app/features/platform/page-metadata.mdx.
Three failure modes are handled without an error:
- No
gitbinary on the build machine — theENOENTcase returns statusunavailablewith the error message kept onerrorReason, and the footer renders nothing. - A file with no commit history, such as a page added but not yet committed —
status
no-history, and the row still renders if an edit URL is set. - A shallow clone (
git clone --depth=1) —git logsees one commit, so the contributor list shrinks to whoever made it. Turn on full clone in your platform's build settings when the history matters.
getGitMeta is wrapped in React's cache(), so the two commands run once per
file per render pass no matter how many times the page asks for them.
The URL shape is GitHub's. GitLab uses /-/edit/, and Bitbucket uses
/src/<branch>/<path>?mode=edit, so those hosts need getEditUrl in
lib/git-meta.ts adjusted.
Options
NEXT_PUBLIC_REPO_URLenvNEXT_PUBLIC_REPO_BRANCHenvDefault: mainBranch segment in the edit URL.
lastUpdatedIsostring | nullrequiredISO 8601 author date of the last commit. Rendered through
toLocaleDateString('en-US', ...) as Aug 16, 2026, inside a <time>
element carrying the raw ISO value in dateTime. An unparseable value prints
as-is instead of throwing.
contributorsGitContributor[]requiredObjects of { name, email }. Only name is rendered; the email is read for
deduplication and never reaches the page.
editUrlstringOptional. Rendered as the "Edit on GitHub" button with an external-link icon.
Omitted when NEXT_PUBLIC_REPO_URL is unset.
MAX_CONTRIBUTORSnumberDefault: 5Hard cap on names, applied after deduplication. A module constant in
lib/git-meta.ts, not a prop.
status'ok' | 'no-history' | 'unavailable'Field on the GitMeta object returned by getGitMeta. Useful if you render
the metadata yourself and want to tell "this repo has no history" apart from
"git could not run".
aria-labelstringDefault: Page metadataLabel on the wrapping <section> so screen readers announce the row as its
own landmark.