# Astro Loader for Obsidian Vaults 🪐🔗

<center>
	<img src="https://github.com/aitorllj93/astro-loader-obsidian/blob/main/packages/astro-loader-obsidian/logo.png" alt="Description" height="200">
</center>

**astro-loader-obsidian** is a content loader for [Astro](https://astro.build/) that lets you treat your [Obsidian](https://obsidian.md/) vault as a native content collection. Easily integrate your markdown notes, assets, and internal links into your Astro site with minimal setup.

## ✨ Features

- 📁 **Load entire Obsidian vaults** as Astro content collections.
- 🔗 **Resolves Obsidian-style links** (`[[Note Title]]`) into proper Astro/HTML links.
- 🖼️ **Image path resolution** for local media files (including support for `![[image.png]]` embeds).
- 📝 **Reads frontmatter** from your notes and exposes publishing metadata (like `publish`, `tags`, `date`, etc).
- ⚡ **Supports Astro's Content Collections API**, including types and schema validation.
- 💡 Lightweight and fast — ideal for digital gardens, knowledge bases, blogs, and more.

## 🚀 Use Cases

- Personal knowledge bases
- Digital gardens
- Developer blogs
- Collaborative wikis

## 🧰 Need a Full Theme?

Check out [`astro-theme-spaceship`](https://github.com/aitorllj93/astro-theme-spaceship) — a ready-to-use theme built specifically for publishing Obsidian vaults with Astro. It includes:

- Preconfigured `astro-loader-obsidian` integration
- Clean, responsive layout
- Built-in support for tags, backlinks, and note metadata
- Dark mode, tree view, and more

## 📦 Installation

```sh
npm i astro-loader-obsidian
```

## 🔧 Usage

1. **Setup your Astro config** to include the loader:

```ts
// content.config.mjs
import { ObsidianDocumentSchema, ObsidianMdLoader } from "astro-loader-obsidian";
import { defineCollection } from 'astro:content';

export const collections = {
	documents: defineCollection({
		loader: ObsidianMdLoader({
			base: 'src/content/vault',
			url: 'docs',
		}),
		schema: ({ image }) => ObsidianDocumentSchema.extend({
      image: image().optional(),
      // or
      cover: image().optional(),
    }),
	}),
};

```

2. **Use your documents as content** in Astro components or pages:

```ts
import { getCollection } from 'astro:content';

const documents = await getCollection('documents');
```

3. **Linking between notes** works automatically:

```astro
<a href={document.data.permalink}>Read: {note.data.title}</a>
```

## 🧠 Frontmatter Support

Astro Loader respects frontmatter metadata in your Obsidian notes. You can use:

```yaml
---
title: "My Note"
date: 2025-04-06
tags: [astro, obsidian]
publish: true
---
```

These fields will be accessible via the `data` object in your content collections.

## 🔗 Obsidian Links

Obsidian-style links like `[[Another Note]]` or `![[image.png]]` are automatically resolved to valid Astro URLs and `<img>` elements, so your content just works without rewriting everything.

### Before

```markdown
Check out [[My Other Note]] for more info.

![[image.png]]
```

### After

```html
<p>Check out <a href="/docs/my-other-note">My Other Note</a> for more info.</p>

<img src="/images/image.png" alt="image.png" />
```

## 📁 Directory Structure

Example vault structure:

```
vault/
├── My Note.md
├── My Other Note.md
├── images/
│   └── image.png
```

Will be available in Astro as:

```
/docs/my-note
/docs/my-other-note
/images/image.png
```

## 🧪 Type Safety

You can extend the schema for your frontmatter using Zod’s `extend` features:

```ts
// content.config.mjs
import { defineCollection, z } from 'astro:content';

export const collections = {
	documents: defineCollection({
		loader: ObsidianMdLoader({
			base: 'src/content/vault',
			url: 'docs',
		}),
		schema: ({ image }) => ObsidianDocumentSchema.extend({
      image: image().optional(),
      // or
      cover: image().optional(),
      myCustomProperty: z.string().optional(),
    }),
	}),
};
```

## 🛠️ Configuration Options

| Option          | Type      | Description                                             |
|-----------------|-----------|---------------------------------------------------------|
| `pattern`  | `string`  | Glob pattern to match files. Defaults to `**/*.md` |
| `assetsPattern`  | `string`  | Glob pattern to match assets. Defaults to `**/*.{svg,png,jpg,jpeg,avif,webp,gif,tiff,ico}` |
| `base`     | `string`  | Base directory to resolve the glob pattern from. Relative to the root directory, or an absolute file URL. Defaults to `.`                     |
| `url`    | `string`  | Base URL where this content should be served. Defaults to collection name. Used for autogenerated permalink                |
| `i18n`  | `boolean` | Enables i18n routing     |
| `author`    | `string`  | Default author                |

## 🙌 Contributing

Contributions welcome! Feel free to open issues or PRs for bugs, features, or docs improvements.

## 📄 License

MIT License © aitorllj93

---

Built with ☄️ [Astro](https://astro.build) and 🧠 [Obsidian](https://obsidian.md)