Daniel Gray

Thoughts, Notes, Ideas, Projects

← Back to home

Blog Architecture - Links and Navigation

This article explores how Obsidian <span class="obsidian-link disabled" data-link="wiki links" title="Link to: wiki links (not yet created)">wiki links</span> become web navigation, how the content tree is built, and how users navigate the blog.

This is part 4 of the Blog Architecture Deep Dive series. Start with Blog Architecture - Overview if you haven't read it yet.

The Power of Wiki Links

In Obsidian, you create links using <span class="obsidian-link disabled" data-link="double brackets" title="Link to: double brackets (not yet created)">double brackets</span>. These aren't just links: they create a knowledge graph. When you link posts together in Obsidian, those links automatically become navigation on the website.

For example:


This blog uses <span class="obsidian-link disabled" data-link="Next.js" title="Link to: Next.js (not yet created)">Next.js</span> for static site generation.

See <a href="/blog/Coding%2FBlog_Architecture%2FBlog_Architecture_-_Overview" class="obsidian-link active" title="Blog Architecture - Overview">Blog Architecture - Overview</a> for more details.

The system automatically:

  • Finds the linked posts

  • Converts them to clickable web links

  • Creates navigation relationships

  • Builds a content tree from the link structure

Link Resolution Process

Converting Obsidian links to web links is one of the most complex parts of the system. The process happens in multiple stages.

Link Formats Supported

The system handles various Obsidian link formats:

  • Simple links: <span class="obsidian-link disabled" data-link="Link Text" title="Link to: Link Text (not yet created)">Link Text</span><a href="/blog/Link_Text">Link Text</a>

  • Display text: <span class="obsidian-link disabled" data-link="Link Text" title="Link to: Link Text (not yet created)">Custom Text</span><a href="/blog/Link_Text">Custom Text</a>

  • Path-based: <span class="obsidian-link disabled" data-link="folder/file" title="Link to: folder/file (not yet created)">folder/file</span> → matches by directory structure

  • Fuzzy matching: Handles variations in spacing and capitalization

Three-Tier Matching Strategy

The link resolver uses a sophisticated matching strategy:

1. Path-based Matching

For links with / (indicating directory structure):

  • Matches against relativePath (preserves directory structure)

  • Case-insensitive

  • Handles URL encoding

Example:

  • Link: <span class="obsidian-link disabled" data-link="Coding/Blog Architecture" title="Link to: Coding/Blog Architecture (not yet created)">Coding/Blog Architecture</span>

  • Matches: File at Coding/Blog Architecture.md

2. Filename Matching

  • Matches against fileName (basename without extension)

  • Also matches last segment of relativePath

  • Handles variations in spacing/capitalization

Example:

  • Link: <span class="obsidian-link disabled" data-link="Blog Architecture" title="Link to: Blog Architecture (not yet created)">Blog Architecture</span>

  • Matches: File named Blog Architecture.md or blog-architecture.md

3. Fuzzy Matching

  • Normalizes both link and filename (removes spaces, special chars)

  • Handles edge cases like "Moon forming Impact" vs "Moon Forming Impact"

Link Processing Pipeline

Links are processed in multiple stages to catch all cases:

  1. Pre-HTML conversion: Process links in markdown before remark converts to HTML

  2. Post-HTML conversion: Catch any escaped links (from code blocks, etc.)

  3. HTML entity handling: Process HTML-escaped brackets

This multi-pass approach ensures links are resolved even in edge cases.

Link States

Links can be in two states:

  • Active: Points to an existing published post → <a href="/blog/slug">

  • Disabled: Points to non-existent post → <span class="obsidian-link disabled"> (styled differently, not clickable)

Disabled links are rendered but not clickable, allowing you to see what you intended to link to even if the post doesn't exist yet.

Building the Content Tree

The blog automatically builds a hierarchical content tree from Obsidian links. This tree powers the Table of Contents and creates natural navigation paths.

Tree Building Algorithm

The tree is built in several steps:

  1. Initialize nodes: Create a node for each post

  2. Establish series hierarchy: Series posts with seriesOrder: 1 become parents

  3. Establish link-based hierarchy: Posts that link to others become parents

  4. Prevent cycles: Check for circular dependencies

  5. Collect root nodes: Posts without parents (or series parents)

  6. Sort: Sort by date (newest first)

Series Hierarchy

Series posts are organized hierarchically:

  • Posts with seriesOrder: 1 become parent nodes

  • Other posts in the series become children

  • This creates a natural series structure in the tree

Example:


The 3D Background (seriesOrder: 1)

├─ 3d Background - Cell Shading (seriesOrder: 2)

├─ 3d Background - Atmospheric Effects (seriesOrder: 3)

└─ 3d Background - Camera System (seriesOrder: 4)

Link-Based Hierarchy

When you link to another post using <span class="obsidian-link disabled" data-link="Post Name" title="Link to: Post Name (not yet created)">Post Name</span>, the system:

  • Establishes relationships: Creates parent-child relationships between linked posts

  • Builds hierarchy: Organizes content into a tree structure based on link patterns

  • Preserves series: Maintains series relationships while incorporating link-based structure

  • Prevents cycles: Ensures the tree structure remains acyclic

The source of the link becomes the parent, and the linked post becomes a child. This creates a "backlink" style hierarchy where the source of the link is the parent.

Cycle Prevention

The system includes cycle detection to prevent infinite loops. This ensures the tree structure remains acyclic, preventing navigation loops.

Navigation Features

The blog provides multiple navigation methods, all powered by the content structure:

1. Table of Contents

Every blog post page includes a Table of Contents sidebar that shows:

  • All blog posts organized hierarchically

  • Series relationships (parent posts with nested children)

  • Your current position in the content structure

  • Quick navigation to any post

The table of contents:

  • Persistent: Stays visible as you scroll

  • Collapsible: Click to show/hide

  • Responsive: Moves to the bottom on mobile devices

  • Auto-scrolls: Scrolls to highlight the current page

2. Linked Posts

At the bottom of each post, you'll find Related Content:

  • Posts that are linked from the current article

  • Discover related topics and follow connections

  • Expand your exploration organically

This creates a natural "related posts" section based on what the author actually links to in their content.

3. Series Navigation

When viewing a post in a series, you'll see:

  • Series header: Shows the series name and current part

  • Series list: All posts in the series with navigation

  • Previous/Next buttons: Move between parts

This provides structured navigation through related content.

4. Category Navigation

Every post is tagged with categories. You can:

  • Browse by category: Click any category tag on a post

  • Category filtering: Use category links to filter posts

  • Multiple tags: Posts can belong to multiple categories

5. Search

The header search provides semantic search across all content:

  • Vector-based: Uses embeddings for semantic understanding

  • Real-time: Results update as you type

  • Contextual: Finds posts by title, excerpt, and categories

URL Structure

The blog preserves your Obsidian directory structure in URLs:


Obsidian Vault/

Coding/

Blog Architecture.md

This Blog.md

Becomes:


/blog/Coding/Blog_Architecture

/blog/Coding/This_Blog

This creates a natural hierarchy that reflects how you organize your content.

URL Encoding

The system carefully handles URL encoding:

  • Encoding: Slugs are encodeURIComponent()'d when creating links

  • Spaces → %20

  • /%2F

  • &%26

  • Decoding: URLs are decodeURIComponent()'d when resolving

  • Handles malformed URLs gracefully (falls back to original)

  • Normalization: Multiple encoding strategies are tried when matching

This ensures links work correctly even with special characters in filenames.

Navigation Design Philosophy

The navigation system is inspired by:

  • Obsidian: Wiki-style linking and graph views

  • Knowledge graphs: Emphasizing connections between ideas

  • Progressive disclosure: Showing structure without overwhelming

  • Multiple entry points: Different ways to discover the same content

Multiple Navigation Methods

The blog provides multiple ways to explore content:

  1. Categories: Browse by topic

  2. Series: Follow structured sequences

  3. Table of Contents: See the full hierarchy

  4. Search: Find specific content

  5. Linked Posts: Follow connections

  6. Series Carousel: Browse series on the home page

This multi-faceted approach ensures users can find content in whatever way feels most natural to them.

Advanced Features

Nested Series

Series can contain sub-series, creating hierarchical structures:

  • Simple series: Part 1 → Part 2 → Part 3

  • Nested series: A series can contain sub-series, like chapters containing sections

  • Series within series: For example, "The 3D Background" contains "Atmospheric Effects" which has its own sub-posts

This structure allows for both broad overviews and deep dives into specific topics.

Content Tree Visualization

The Table of Contents reflects the tree structure, showing:

  • Root nodes: Posts that aren't linked from other posts (or are series parents)

  • Child nodes: Posts that are linked from parent posts

  • Series grouping: Series posts are grouped under their parent, with link-based children nested within

This creates a natural navigation flow that follows the connections you've made in your notes.

Conclusion

The link resolution and navigation system transforms Obsidian's wiki-style linking into a rich web navigation experience. By building a content tree from links and series, the blog creates natural navigation paths that reflect how you organize your thoughts.

The result is a navigation system that:

  • Emerges naturally from your content structure

  • Provides multiple ways to explore content

  • Maintains the connections you make in Obsidian

  • Creates an intuitive browsing experience

Next Steps

Continue to Blog Architecture - Build and Deployment to learn about the build process, static generation, and deployment.

Related Content


This article is part of the Blog Architecture Deep Dive series. Previous: Blog Architecture - From Markdown to Web. Next: Blog Architecture - Build and Deployment.

Explore Categories

Related Content

Blog Architecture - Overview

Blog Architecture - Overview This is the first in a series of articles exploring the architecture of this blog. We'll start with a high-level overview that anyone can understand, then progressively di...

Blog Architecture - Advanced Features

Blog Architecture - Advanced Features

Blog Architecture - Advanced Features This article explores the advanced features of the blog: semantic search, series organization, table of contents, and other sophisticated navigation and discovery...

Blog Architecture - Why Obsidian?

Blog Architecture - Why Obsidian?

Blog Architecture - Why Obsidian? This article explores why Obsidian was chosen as the authoring tool for this blog and how its unique features integrate with the web publishing system. This is part 2...

Blog Architecture - From Markdown to Web

Blog Architecture - From Markdown to Web

Blog Architecture - From Markdown to Web This article explores the content processing pipeline: how Obsidian markdown files are transformed into web pages. We'll trace a file's journey from your Obsid...

Navigating Blog Content

Navigating Blog Content

Navigating Blog Content !images/Pasted image 20251123205959.png This blog is designed with multiple ways to explore and discover content, inspired by tools like Obsidian that emphasize connections and...

Blog Design

Blog Design This page serves as a hub for all articles about the design and architecture of this blog. For Readers - Navigating Blog Content - Guide to all navigation methods and features for users of...