An engineering blog becomes more useful when an article is not an isolated page. It should remain readable as ordinary prose, connect to the work around it, expose enough structure for search engines and machine readers, and require almost no publishing maintenance. This article documents the current system and deliberately exercises its major features.
The boundary is intentionally simple: Markdown owns the writing, Next.js owns the presentation, Git owns the history, and Vercel owns deployment. A small compiler connects those responsibilities without introducing a CMS or a second website stack.
The publishing architecture#
A note begins as local Markdown. Frontmatter supplies its stable title, summary, dates, aliases, publication status, and tags. The build validates that contract, resolves internal references, calculates indexes, and emits static or server-rendered HTML alongside machine-readable representations.
Publication is explicit. A file must be inside a public collection and declare
publish: true; private vault material is never copied into the site. The
repository also includes a publishing command that validates notes before they
cross that boundary.
Frontmatter is a contract#
title: "Building a Connected Engineering Blog with Next.js"
description: "How the connected publishing system works."
publish: true
status: reference
created: "2026-07-17"
updated: "2026-07-17"
tags:
- Next.js
- software engineering
aliases:
- Connected Engineering Notestitle: "Building a Connected Engineering Blog with Next.js"
description: "How the connected publishing system works."
publish: true
status: reference
created: "2026-07-17"
updated: "2026-07-17"
tags:
- Next.js
- software engineering
aliases:
- Connected Engineering NotesThe three statuses describe editorial state without relying on a gardening metaphor:
| Status | Meaning | Expected use |
|---|---|---|
| Brief | A concise observation or working idea | Quick technical findings |
| Developing | A note that is still being expanded | Active investigations |
| Reference | A complete article intended for repeated use | Durable explanations |
The quality gate rejects missing titles, malformed dates, unsafe or duplicate routes, unresolved public wikilinks, missing images, invalid frontmatter, and secret-like values. TypeScript, ESLint, and the production build run before a change is published.
The publishing command is the boundary#
The private writing vault and website repository remain separate. The
repository's publishing command reads only the selected public folder and only
files with publish: true:
npm run publish:notes -- \
--source=/absolute/path/to/Vault/Public \
--attachments=/absolute/path/to/Vault/Attachments \
--build \
--pushnpm run publish:notes -- \
--source=/absolute/path/to/Vault/Public \
--attachments=/absolute/path/to/Vault/Attachments \
--build \
--pushIt validates titles, aliases, paths, and wikilinks; converts Obsidian image
embeds; copies referenced attachments into hashed public asset names; removes
files from the previous publishing manifest; validates the resulting public
corpus; optionally runs the production build; and commits and pushes only the
generated notes, assets, and publishing manifest. Replacing --build --push
with --check performs a non-mutating eligibility check.
That's the documented path, but it isn't the only one in active use. Obsidian R2 Workflow describes how a growing share of notes, including this one, are written and edited directly in this repository instead of round-tripping through the vault, while still passing through the same validation and build gate before they go live.
Connections are part of the content model#
Markdown links and Obsidian-style wikilinks are resolved during compilation. For example, Ship of Theseus resolves through its title or alias to a normal, accessible HTML link. The target then receives a backlink automatically.
For every note , the compiler records outgoing edges. Reversing them produces backlinks:
That shared index powers:
- connected notes at the end of an article;
- backlinks from notes that cite the current page;
- related entries inferred from tags and graph proximity;
- navigable internal-link previews;
- the compact and full notes graphs.
PageRank identifies influential notes#
The notes index provides Top, Name, and Latest sorting. Top is not a manual editorial order: it follows PageRank over explicit internal links. For node , the iterative score is:
where and is the number of outgoing links from . Dangling rank is redistributed across the graph, and iteration stops after convergence. The highest-ranked note begins at the center of the visualization; subsequent notes settle in progressively wider reference rings.
Girvan–Newman reveals link communities#
PageRank answers which notes are influential, while Girvan–Newman answers which notes form communities. The build calculates edge betweenness with Brandes' algorithm, removes the most central bridge, recomputes betweenness, and repeats until a useful number of connected components appears. Community membership controls node color.
The full notes graph combines those results with a physical simulation:
- PageRank controls centrality and initial order;
- Girvan–Newman communities control color;
- circle area represents article word count;
- explicit links behave like springs;
- repulsion and collision keep nodes legible;
- panning, zooming, dragging, and hover inspection remain interactive.
A compact framed graph is also embedded directly in /notes. Its initial
render fits every node inside the frame and expands outward from the center.
The accessible list beneath the canvas preserves every graph destination for
keyboard users and non-visual readers.
Finding and browsing published work#
Discovery is deliberately available without making the graph the only way to navigate.
Search, sorting, and responsive pagination#
The Notes page searches titles, summaries, folders, and tags. All Posts searches both modern notes and legacy essays. The global Cmd/Ctrl +
K palette searches notes, essays, tags, and photos from one compact generated index; pressing / while not typing opens the same search. Photo results retain their thumbnails rather than being reduced to generic text rows.
Pagination follows viewport capacity:
| Collection | Mobile | Tablet | Desktop |
|---|---|---|---|
| Notes | 4 | 6 | 8 |
| All Posts | 6 | 10 | 14 |
Filtering resets pagination to the first valid page, while URLs retain a shareable page number.
List and grid orientation#
Every primary content collection has an accessible List/Grid switch:
- the Notes index;
- individual folders and topic pages;
- All Posts;
- latest writing on the landing page;
- Photos;
- the folder browser itself.
List mode favors scanning metadata in sequence. Grid mode gives each result a
self-contained card, similar to a compact research-note catalogue. The
orientation buttons expose aria-pressed state and work without hiding content
from assistive technology. Each page remembers its own choice, so changing Notes
does not alter Photos, All Posts, the landing page, or a specific folder or tag
page. Card grids use one column on mobile, two on medium screens, and three equal
columns on wide screens while remaining inside the same site body width.
Folder browsing now belongs inside Notes instead of the landing dashboard.
This keeps the home page focused on recent writing while /notes owns search,
folders, topics, publication status, and graph exploration.
Photos participate in discovery#
Photos are first-class search documents rather than a disconnected gallery. Global search results include thumbnails and navigate directly to photo pages. The Photos page has its own search and List/Grid control: grid mode provides a visual gallery and dialog, while list mode includes the thumbnail, description, location, engagement counts, and a permanent detail link. Photo dialogs and detail pages expose views, one-time likes, private feedback, and native sharing with clipboard fallback. On touch devices, a deliberate press-and-hold gesture can share directly from the grid without first opening the dialog.
The first above-the-fold image loads eagerly for good Largest Contentful Paint; the remaining images remain lazy. The photo search/view toolbar takes over the top edge only after the normal site header has scrolled away.
Technical prose renders like technical prose#
The renderer supports GitHub-flavoured Markdown, mathematical notation, language-aware code, diagrams, tables, task lists, quotations, and deep heading structure. The output is semantic HTML rather than a client-only editor.
Mathematics with LaTeX#
Inline expressions such as stay within the sentence. Display expressions use KaTeX:
Code with theme-aware highlighting#
Fenced code retains its language and exposes a copy control:
type PublicationStatus = "brief" | "developing" | "reference";
function canPublish(input: { publish: boolean; status: PublicationStatus }) {
return input.publish && input.status !== "brief";
}type PublicationStatus = "brief" | "developing" | "reference";
function canPublish(input: { publish: boolean; status: PublicationStatus }) {
return input.publish && input.status !== "brief";
}Light mode uses a paper-like surface and dark syntax. Dark mode uses an ambient surface with light, language-aware tokens. Both keep the code distinct without turning it into an unrelated black rectangle.
Tables, tasks, and quotations#
Tables use a complete cell grid at every viewport size, with overflow available when technical content is wider than the reading column.
- validate public metadata;
- resolve wikilinks and backlinks;
- calculate PageRank and communities;
- generate search, feeds, sitemap, and machine-readable text;
- render diagrams, mathematics, and highlighted code;
- provide list and grid discovery modes;
- keep improving the writing itself.
The publishing system should disappear during writing and become strict only at the boundary where private thought turns into public information.
Reading without interface noise#
Every published note omits the global site header, regardless of its collection, so the page begins with the article itself. Collection indexes, graphs, photos, and supporting pages retain the normal navigation. A fixed top-right reading percentage, extracted table of contents that highlights the nearest section, and active-heading state provide orientation without crowding the reading column or placing a bar over the text. When the contents list is longer than its frame, it scrolls itself to keep the current section in view on desktop and whenever the mobile panel opens. A fixed close control returns directly to the complete Notes index from every collection. On mobile, the table of contents collapses into a small fixed icon beside the configurator and reading percentage; selecting a section navigates to it and dismisses the section menu. After a contents jump, the close control temporarily becomes a back arrow labelled with the previous section; returning there restores the usual close action.
A neighboring reading control stays collapsed until requested. It offers the site's default typeface plus five self-hosted reading fonts—Inter, Atkinson Hyperlegible, Source Serif 4, Lora, and Merriweather—text sizing from 90% to 120%, left, center, right, or justified alignment, narrow or wide reading widths, and bright or dark page tones. Choosing Site default removes the article-level font override; the other choices persist across articles while leaving code in its monospace typeface and keeping the document structure unchanged for browser reader modes. Wide reading mode uses the broader article column while retaining the desktop On this page sidebar by default. A reader can collapse that sidebar into a compact dialog button and pin it back onto the page from inside the dialog; the preference persists across articles.
Selecting a word or phrase in an article reveals a small Look up action. The definition panel resolves site-specific terms, WordNet entries, computer-science terms, and engineering idioms from local dictionaries, then presents every matching source together. The selected text stays on the server that already serves the site; lookup does not send reading activity to an external dictionary service.
Breadcrumbs remain available across notes, folders, topics, graphs, photos, and
archive pages. On articles they describe Home → Notes → Folder → Article in
both visible navigation and BreadcrumbList structured data.
Each note footer includes an email-feedback action addressed to the site owner.
The generated message subject is Feedback: <note title>, and its body includes
the canonical note URL so feedback retains its context outside the browser.
The semantic main, article, headline, author, dates, headings, and
articleBody markers give browser reader modes a clean extraction target. The
same article also has a direct raw Markdown representation, so immersive readers
and machines do not need to reverse-engineer the interactive layout.
Navigable previews#
Internal references open a preview containing the target title, summary, folder, and publication status. The entire preview is navigable, not just its small title. Supported external references—such as Wikipedia's overview of hypertext— load a title, extract, description, and image, and likewise remain clickable.
Visual system and accessibility#
The default appearance for a new visitor is dark, with #1f1e1d as the main
canvas. Supporting cards, popovers, borders, and muted text use a warm neutral
palette rather than blue-grey black. Explicit Light, Dark, and System choices
remain available and are respected on subsequent visits.
List and grid cards use the same restrained corner radius as the primary landing page buttons, keeping repeated content surfaces precise without making every panel feel like a floating container.
The typography is self-hosted, including the five optional reading fonts, and adds no external font request:
- Inter for interface and default reading text;
- Roboto Mono for dates, labels, metadata, and code-adjacent details;
- KaTeX's mathematical fonts for formulas.
The layout uses visible focus states, semantic landmarks, skip navigation, accessible graph destinations, labelled control groups, reduced-motion rules, and responsive content widths. Interactive flourishes never replace the normal link or text representation.
The global header, page body, and footer share one content container and the same responsive gutters, keeping their left and right edges aligned across notes, indexes, graphs, photos, and supporting pages. On pages that retain the global header, it stays in normal document flow and scrolls away instead of occupying the viewport throughout the visit.
SEO and machine readability#
Good discovery begins with complete HTML. Each article receives a unique title
and description, canonical URL, publication and modification dates, Open Graph
and Twitter metadata, large image previews, and TechArticle structured data.
The sitemap and Atom feed enumerate public content, while stable headings and
internal links make the documents understandable without running the graph or
search interfaces.
The Atom feed is advertised in page metadata for automatic discovery. A
human-readable /subscribe page provides one-click Feedly and Inoreader links,
the raw feed, a copyable feed URL, and setup instructions for any other reader.
Machine readers receive multiple coordinated entry points:
robots.txtexplicitly permits major search and user-fetch agents;llms.txtdescribes the author and canonical collections;llms-full.txtprovides the full public corpus with metadata and URLs;/raw/[folder]/[slug]provides per-article Markdown;- every article advertises its Markdown alternate;
- the footer exposes the AI index and subscription guide as normal links.
The crawler policy covers current agents from OpenAI, Anthropic, Perplexity, Google, Microsoft, Meta, and Apple, with a permissive fallback for other readers. This cannot force a model to browse or cite the site, but it removes avoidable technical barriers.
Design references and implementation choices#
Two independent sites helped clarify the product direction. Bibek Panthi's connected notes demonstrate the value of backlinks, a physical link graph, lightweight static pages, and a clear feed-subscription path. Hugo Cisneros's Notes show how a searchable notes index can remain calm, compact, and useful without becoming a dashboard.
This implementation borrows those interaction principles rather than either site's stack or visual identity. It keeps the existing Next.js application, uses the site's own content compiler and design tokens, treats the output as a professional engineering archive, and avoids metaphorical publication labels.
One source, several representations#
| Consumer | Representation |
|---|---|
| Reader | Semantic HTML, reading controls, TOC, lookup, and feedback |
| Search engine | Canonicals, JSON-LD, sitemap, metadata, and internal links |
| Feed reader | Atom entries and a human-readable subscription guide |
| Site search | Generated notes, essays, tags, and photo documents |
| Notes graph | PageRank, communities, word counts, and explicit edges |
| AI crawler | HTML, per-article Markdown, llms.txt, and llms-full.txt |
Correcting a title or adding a link updates the page, breadcrumb, search result, graph label, backlink index, feed metadata, sitemap, and machine-readable corpus from the same source.
Current public routes#
| Route | Purpose |
|---|---|
/notes | Search, folders, topics, statuses, and graph |
/notes/graph | Full interactive notes graph |
/all-posts | Unified modern and legacy archive |
/photos | Searchable list/grid photo collection |
/photos/[id] | Canonical photo detail and engagement page |
/tags/[tag] | Topic-specific note results |
/raw/[folder]/[slug] | Plain Markdown representation |
/search-index.json | Generated global-search document index |
/robots.txt | Search and AI crawler policy |
/sitemap.xml | Search discovery index |
/atom | Feed-reader representation |
/subscribe | Human-readable feed subscription guide |
/llms.txt | Machine-oriented site guide |
/llms-full.txt | Full machine-readable public corpus |
Legacy /knowledge URLs permanently redirect to /notes, preserving old links
without keeping outdated public terminology.
What the reader should notice#
The system is broad, but the article remains the main object. Search is quick, the table of contents is quiet, previews appear only when requested, the graph starts fitted to its frame, and each interactive view has a normal link-based equivalent.
This page demonstrates the system in one ordinary Markdown file: validated metadata, aliases, publication status, headings and table of contents, LaTeX, Mermaid, highlighted code, tables, tasks, tags, a wikilink, backlinks, related notes, reading progress, mobile and desktop orientation, text lookup, adjustable reading presentation, close navigation, note-specific email feedback, internal and Wikipedia previews, structured data, responsive discovery, feed subscription, sitemap inclusion, reader-mode semantics, and machine-readable full text. That portability is the most important feature: the writing remains useful even outside the site that presents it.