# Multiple Trees

Docs sites are often split into parts, such as “Guides” and “API Reference”: each part has its own sidebar, and previous and next links never cross from one into another. Call `defineTree` on the same collection several times, with each tree holding only its own pages.

## Defining them

```ts
// src/lib/docs.ts
const guides = await defineTree(entries, ({ page, dir }) => [page('guides', dir('guides'))]);
const api = await defineTree(entries, ({ page, dir }) => [page('api', dir('api'))]);

export const sections = [
  { label: 'Guides', href: toHref('docs', 'guides'), tree: guides },
  { label: 'API Reference', href: toHref('docs', 'api'), tree: api },
];
```

`sections` is your own data, unknown to minidocs. Names, entry pages and whether to add icons are all up to you.

## Which tree the current page is in

Find the tree that contains the current page with `findPath`:

```ts
const section = sections.find((section) => findPath(section.tree, id).length > 0) ?? sections[0];
const nav = navState(section.tree, id);
const { prev, next } = neighbors(section.tree, id);
```

From there, the sidebar and previous and next links use `section.tree`, written the same way as with a single tree.

Use `findPath` rather than `id.startsWith('api')`, so the structure of the trees is written in one place only.

Pages in no tree, such as the home page, fall back to `?? sections[0]`; you can show no sidebar for them instead. When a page appears in two trees, `find` takes the one listed first in `sections`.

## A switcher

The switcher is your own HTML, like a language switcher:

```astro
<nav aria-label="Sections">
  {sections.map((item) => (
    <a href={item.href} aria-current={item === section ? 'true' : undefined}>
      {item.label}
    </a>
  ))}
</nav>
```

Each link points to the entry page of its part, which is not necessarily the current page, so `aria-current` is `true` rather than `page`.

## Multilingual sites

Make `sections` a function of the locale, where `t` holds your own interface text:

```ts
export const sections = (locale: Locale) => [
  { label: t[locale].guides, href: toHref('docs', 'guides', locale), tree: guides[locale] },
  { label: t[locale].api, href: toHref('docs', 'api', locale), tree: api[locale] },
];
```

## llms.txt and search

- llms.txt: generate one per tree, or join the nodes into one: `toLlmsTxt([...guides, ...api], { title })`. The top node with children in each tree becomes a section, see [llms.txt](/en/docs/guides/markdown.md#llmstxt)
- Search: write the tree’s name into a filter, such as ``data-pagefind-filter={`tree:${section.label}`}``, and add radio buttons named `tree`, see [Filtering by group](/en/docs/guides/search.md#filtering-by-group)

## When to use multiple collections

Trees of one collection share its URL prefix and frontmatter schema. Content with a different prefix and different fields, such as a changelog under `/changelog/` with a date on every release, belongs in another collection, see [Multiple Collections](/en/docs/guides/collections.md).
