stnd.buildSTANDARD MANUAL2026-08-08
STD-STND-LOA

@stnd/loader

@stnd/loader

Overview

Content ingestion loaders for the Standard Ecosystem, built as custom Astro Content Collection Loaders.

ELI5

This is how an Astro site’s content collections point at something that isn’t a local src/content/ folder — an Obsidian vault (with wikilinks and frontmatter) or a Notion database. Define the collection once with the right loader, then use getCollection() like any normal Astro content collection.

Usage

Use it (vault):

import { defineCollection } from "astro:content";
import { vaultLoader } from "@stnd/loader-vault";
export const collections = {
  vault: defineCollection({ loader: vaultLoader({ path: "../../vault/Atelier" }) }),
};

Loaders

1. Vault Loader (@stnd/loader-vault)

Loads content from a local directory containing Markdown files with Obsidian-style frontmatter, wikilinks ([[link]]), and media files.

Configuration (src/content.config.ts)

import { defineCollection } from "astro:content";
import { vaultLoader } from "@stnd/loader-vault";

const vault = defineCollection({
  loader: vaultLoader({
    path: "../../vault/Atelier", // path to the local Obsidian vault
    flattenDirectories: false,   // preserve directory structure in IDs
    ignore: [".obsidian", ".trash", ".agent"], // directories to ignore
  }),
});

export const collections = { vault };

Astro Dev Mode Workaround (Important)

Warning

In Astro 6.x/7.x development mode (astro dev), calling getCollection("vault") inside routes injected via injectRoute() (used by plugins/integrations) returns []. This is due to virtual module hydration issues inside Vite SSR context.

To work around this, the vault loader populates a global singleton that survives HMR and SSR code-splitting. Instead of using getCollection, import the vault singleton directly:

import { vault } from "@stnd/loader-vault";

// Wait for the vault to initialize (optional, useful in edge cases)
await vault.ensureLoaded();

// Access entries and metadata
const entries = vault.entries; // Array of VaultEntry
const size = vault.size;       // Number of entries
const meta = vault.meta;       // { validLinks, imageIndex, vaultPath }

// Find individual entries
const note = vault.getEntry("my-permalink");

2. Notion Loader (@stnd/loader-notion)

Synchronizes content from Notion databases into the Standard Ecosystem.

Configuration (src/content.config.ts)

import { defineCollection } from "astro:content";
import { notionLoader } from "@stnd/loader-notion";

const notion = defineCollection({
  loader: notionLoader({
    auth: import.meta.env.NOTION_API_KEY,
    databaseId: import.meta.env.NOTION_DATABASE_ID,
  }),
});

export const collections = { notion };

Notes / Observations

(jot down anything noticed here — quirks, gotchas, ideas)

Todo

  • [ ] Evaluate experimental.collectionStorage: 'chunked' for the vault collection — Astro 7.1.6 added a chunk-size option, and @astrojs/cloudflare 14.1.7 fixed chunked-collection loading on the adapter. Only worth it if the vault store is actually large enough to justify it; measure the serialized store first rather than adopting on principle. Note this is unrelated to the dev-mode getCollection workaround (root README #1), which chunking does not address. [priority:: 2] [token_scale:: 3] [created:: 2026-08-07] [area:: framework]