This walkthrough takes a folder of Markdown notes — an Obsidian vault, or any notes directory — and turns it into a published digital garden with working wikilinks, backlinks, tags, a blog, and an RSS feed. Allow twenty minutes.
You'll need italic installed.
italic new my-garden
cd my-gardenCopy your notes into content/ (a few sample notes work fine too):
cp -R ~/vault/* content/Italic doesn't care how the folder is organized — keep your existing structure. Serve it:
italic serveOpen http://localhost:3000. Your notes are already pages: [[wikilinks]]
resolve with Obsidian's fuzzy matching, and every resolved link is feeding a
backlink graph we'll render shortly. Leave serve running; everything below
reloads live.
Unstyled HTML is honest but bleak. Create templates/base.html:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>{{ page.title }} | {{ site.title }}</title>
</head>
<body>
<main>
<h1>{{ page.title }}</h1>
{{ page.content | safe }}
</main>
<aside>
<h2>Linked from</h2>
<ul>
{% for src in page.id_path | backlinks %}
<li><a href="{{ src.id_path | link }}">{{ src.title }}</a></li>
{% endfor %}
</ul>
<h2>Related</h2>
<ul>
{% for doc in page.id_path | related(limit=5) %}
<li><a href="{{ doc.id_path | link }}">{{ doc.title }}</a></li>
{% endfor %}
</ul>
</aside>
</body>
</html>And tell italic to use it for everything. In config.yaml:
site:
title: My Garden
collections:
notes:
path: "**/*.md"
defaults:
notes:
template: base.htmlThe notes collection matches every Markdown file, and its defaults: entry
assigns the layout — no per-file frontmatter needed. Each note now shows its
backlinks (who links here) and related pages (scored across shared
tags and the link graph).
In config.yaml:
taxonomies:
- tags
hashtags: trueNow tags: [...] frontmatter and inline #hashtags in note bodies both
feed the tags taxonomy — and sharpen the related-pages scoring. Give a few
notes some tags.
Create archives/tags.html to generate one page per tag:
---
kind: taxonomy
taxonomy: tags
permalink: /tags/:term/
template: base.html
---
{% for post in pagination.items %}
<p><a href="{{ post.id_path | permalink }}">{{ post.title }}</a></p>
{% endfor %}Visit /tags/<some-tag>/ to see it.
A garden and a blog can share a site. Put dated posts in content/posts/ and
add to config.yaml:
collections:
notes:
path: "**/*.md"
posts:
path: "posts/*.md"
order_by: date
sort: desc
defaults:
notes:
template: base.html
posts:
template: base.html
permalink: /blog/:yyyy/:slug/And a reverse-chronological archive at /blog/, archives/blog.html:
---
kind: collection
collection: posts
permalink: /blog/
per_page: 10
template: base.html
---
{% for post in pagination.items %}
<p>
<a href="{{ post.id_path | permalink }}">{{ post.title }}</a>
<time>{{ post.date | date(format="%Y-%m-%d") }}</time>
</p>
{% endfor %}archives/feed.xml:
---
kind: collection
collection: posts
permalink: /feed.xml
limit: 20
---
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>{{ site.title }}</title>
<link>{{ "" | absolute_url }}</link>
<description>{{ site.description }}</description>
{% for post in pagination.items %}
<item>
<title>{{ post.title }}</title>
<link>{{ post.id_path | permalink }}</link>
<pubDate>{{ post.date | date(format="%a, %d %b %Y %H:%M:%S +0000") }}</pubDate>
</item>
{% endfor %}
</channel>
</rss>For the feed's absolute URLs, set your site's origin in config.yaml:
site:
title: My Garden
url: https://example.comitalic buildEverything lands in public/ as plain static files. Drafts
(draft: true notes) are excluded automatically. Pick a host and ship it —
recipes for GitHub Pages, Netlify, Cloudflare Pages, and rsync are in the
Deployment guide.
- Style it: wrap the layout in CSS, or adopt a theme.
- Permalinks — clean URLs for everything.
- Components — video embeds and shortcodes in your notes.
- Migration guide — coming from Jekyll, Hugo, or Quartz.