Files
beardrive/web/docs/astro.config.mjs
T
8931004b4a docs: use cases move to the marketing site, and the logo goes home (#153)
The seven use-case pages were the one part of docs.beardrive.ai that wasn't
documentation — job-shaped routing pages, aimed at someone deciding rather
than someone building. beardrive.ai already publishes six of them, same
titles, same slugs, so the docs copy was a fork of marketing copy that no one
was keeping in step.

They're deleted here, and every URL redirects to its counterpart over there
rather than to an index: those pages were live and indexed for a month, and
sending all seven to /use-cases/ would throw away which one someone asked
for. shared-skills is the exception — the landing site has no page for it
yet, so that one lands on the index.

The logo now points at beardrive.ai. Starlight always aims it at the docs
root and has no config for it, so this is a SiteTitle component override:
its own markup, one changed href, minus the two-logo branch this site never
takes (one `src`, so the light/dark alternate can't render).

Three off-site links — Use cases, Blog, GitHub — go at the BOTTOM of the
sidebar. The sidebar order is the recommended path, so a link that leaves
the docs must not sit above the docs.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 19:02:50 -07:00

192 lines
8.7 KiB
JavaScript

// @ts-check
import { defineConfig } from "astro/config";
import starlight from "@astrojs/starlight";
import sitemap from "@astrojs/sitemap";
import llmsTxt from "starlight-llms-txt";
import { execFileSync } from "node:child_process";
// docs.beardrive.ai — the public product documentation.
//
// This is a standalone static site, deliberately NOT embedded into the Go
// binary the way the hub frontend (internal/webapp/static) and the cloud
// landing page (cloud/internal/landing/dist) are. Docs change far more often
// than the binary does, and a Pagefind search index has no business shipping
// inside every self-hoster's install. It deploys on its own, on push.
//
// It lives in the OSS repo because that's what it documents: the CLI, the sync
// model, self-hosting. "Edit this page" resolves to something an outside
// contributor can actually open a PR against.
// `lastmod` for the sitemap, from the commit that last touched each page.
//
// The tempting shortcut — stamp every URL with the build time — is worse than
// emitting nothing: a sitemap that reports the whole site changed on every
// deploy teaches Google to disregard its lastmod entirely, and freshness is
// most of what a sitemap is for on a docs site.
//
// Which is also why the shallow check exists. A CI checkout is depth-1 by
// default, and there `git log` attributes every file to the one commit it has
// — the same uniform lie in a different costume. No history, no lastmod.
// (A host that wants these dates must clone with full history:
// actions/checkout needs `fetch-depth: 0`.)
const lastmodBySource = (() => {
const git = (...args) =>
execFileSync("git", args, { cwd: import.meta.dirname, encoding: "utf8" }).trim();
try {
if (git("rev-parse", "--is-shallow-repository") === "true") return new Map();
// One `git log` for every page rather than one per page. Newest commit
// first, so the first time a path appears is its last modification.
const log = git("log", "--format=%cI", "--name-only", "--relative", "--", "src/content/docs");
const map = new Map();
let when = "";
for (const line of log.split("\n")) {
if (!line) continue;
else if (/^\d{4}-\d\d-\d\dT/.test(line)) when = line;
else if (!map.has(line)) map.set(line, when);
}
return map;
} catch {
return new Map(); // built from a tarball, or no git installed — not fatal
}
})();
/** `/reference/cli/` -> the date on `src/content/docs/reference/cli.md`. */
function lastmodFor(url) {
const slug = new URL(url).pathname.replace(/^\/|\/$/g, "") || "index";
for (const ext of [".md", ".mdx"]) {
const at = lastmodBySource.get(`src/content/docs/${slug}${ext}`);
if (at) return at;
}
}
export default defineConfig({
site: "https://docs.beardrive.ai",
// The docs were reorganized around the agent-first path; these URLs were
// public and indexed. Astro emits meta-refresh pages for static output —
// real 301s belong in the host config (see README, "Deploying").
redirects: {
"/start/install": "/manual/install/",
"/start/quickstart": "/manual/setup-by-hand/",
"/guides/connect-an-agent": "/start/setup/",
"/manual/skills-and-hooks": "/manual/hooks/",
// Use cases moved to the marketing site, which already published the same
// six pages at the same slugs. They were live and indexed here for a
// month, so every one of them keeps a redirect — off-site, which is
// exactly what a page that is no longer documentation should do.
"/use-cases/team-artifacts": "https://beardrive.ai/use-cases/team-artifacts",
"/use-cases/team-wiki": "https://beardrive.ai/use-cases/team-wiki",
"/use-cases/business-context": "https://beardrive.ai/use-cases/business-context",
"/use-cases/company-brain": "https://beardrive.ai/use-cases/company-brain",
"/use-cases/personal-wiki": "https://beardrive.ai/use-cases/personal-wiki",
"/use-cases/multi-device": "https://beardrive.ai/use-cases/multi-device",
// The one with no counterpart over there yet — land on the index rather
// than a 404 someone else's deploy has to fix.
"/use-cases/shared-skills": "https://beardrive.ai/use-cases/",
},
integrations: [
// Starlight adds @astrojs/sitemap itself, but only when the config hasn't
// already — declaring it here replaces that default rather than doubling
// it, which is the supported way to reach these options. (Starlight's own
// version only sets `i18n`, and this site is single-language.)
sitemap({ serialize: (item) => ({ ...item, lastmod: lastmodFor(item.url) }) }),
starlight({
title: "BearDrive",
description:
"Google Drive for AI agents. One shared folder your whole team's agents read and write — real files, synced in seconds, with history, provenance, and share links.",
logo: { src: "./src/assets/bear.svg", alt: "BearDrive" },
// The logo is the way back to beardrive.ai. Starlight always points it
// at the docs root, so the link lives in a component override.
components: { SiteTitle: "./src/components/SiteTitle.astro" },
customCss: ["./src/styles/tokens.gen.css", "./src/styles/custom.css"],
social: [
{
icon: "github",
label: "GitHub",
href: "https://github.com/runbear-io/beardrive",
},
],
editLink: {
baseUrl:
"https://github.com/runbear-io/beardrive/edit/main/web/docs/",
},
// Docs are the top AI-citation surface for a dev tool, so ship the
// machine-readable index too: /llms.txt and /llms-full.txt.
//
// Convention puts llms.txt at the ROOT domain, not a docs subdomain.
// beardrive.ai/llms.txt should redirect (or proxy) here — that lives in
// the cloud landing, and is the one cross-repo coordination point this
// split introduces.
plugins: [llmsTxt()],
sidebar: [
{
// The reading order IS the recommended path, and the recommended path
// is agent-first: nobody should meet `brew install` before they meet
// /beardrive:install. Everything CLI lives under "Manual setup",
// one click away and never on the critical path.
label: "Start here",
items: [
{ label: "What is BearDrive?", slug: "" },
{ label: "Set up with your agent", slug: "start/setup" },
{ label: "Your first hour", slug: "start/first-hour" },
],
},
{
// Guides are about working with agents — that's what the product is
// for. Command-by-command CLI detail belongs in Reference.
label: "Working with agents",
items: [
{ label: "Shared agent memory", slug: "guides/shared-agent-memory" },
{ label: "Artifacts and links", slug: "guides/agent-artifacts" },
{ label: "What agents read", slug: "guides/what-agents-read" },
{ label: "Scoping the folder", slug: "guides/scoping" },
],
},
{
// For people who would rather type it, and for machines with no agent
// on them. Same destination, more steps.
label: "Manual setup (optional)",
items: [
{ label: "Install the CLI", slug: "manual/install" },
{ label: "Set up by hand", slug: "manual/setup-by-hand" },
{ label: "Hooks in detail", slug: "manual/hooks" },
],
},
{
label: "Self-hosting",
items: [
{ label: "Run a hub", slug: "self-hosting/run-a-hub" },
{ label: "Authentication", slug: "self-hosting/authentication" },
{ label: "Database", slug: "self-hosting/database" },
],
},
{
label: "Reference",
items: [
{ label: "CLI", slug: "reference/cli" },
{ label: "Project files", slug: "reference/project-files" },
{ label: "Hub config", slug: "reference/hub-config" },
{ label: "Migrate between hubs", slug: "reference/migration" },
],
},
{
label: "Concepts",
items: [
{ label: "How sync works", slug: "concepts/how-it-works" },
{ label: "Project permissions", slug: "concepts/permissions" },
],
},
// Off-site, and last on purpose: the sidebar order is the recommended
// path, so nothing that leaves the docs belongs above the docs.
{
label: "More",
items: [
{ label: "Use cases", link: "https://beardrive.ai/use-cases/" },
{ label: "Blog", link: "https://beardrive.ai/blog/" },
{ label: "GitHub", link: "https://github.com/runbear-io/beardrive" },
],
},
],
}),
],
});