diff --git a/docs.json b/docs.json
index 500bb1a8d..5c92ad2cc 100644
--- a/docs.json
+++ b/docs.json
@@ -25,31 +25,32 @@
},
"navbar": {
"links": [
- {
- "label": "Home",
- "href": "https://langbot.app/en"
- },
{
"label": "Cloud",
- "href": "https://space.langbot.app/cloud?language=en"
+ "href": "https://space.langbot.app/cloud?language=en",
+ "icon": "cloud"
},
{
"label": "Extensions",
- "href": "https://space.langbot.app/market?language=en"
+ "href": "https://space.langbot.app/market?language=en",
+ "icon": "blocks"
},
{
"label": "Blog",
- "href": "https://langbot.app/en/blog"
+ "href": "https://langbot.app/en/blog",
+ "icon": "newspaper"
},
{
"label": "Roadmap",
- "href": "https://langbot.app/en/roadmap"
+ "href": "https://langbot.app/en/roadmap",
+ "icon": "map"
}
],
"primary": {
"type": "button",
"label": "GitHub",
- "href": "https://github.com/langbot-app/LangBot"
+ "href": "https://github.com/langbot-app/LangBot",
+ "icon": "github"
}
},
"footer": {
@@ -780,31 +781,32 @@
],
"navbar": {
"links": [
- {
- "label": "Home",
- "href": "https://langbot.app/en"
- },
{
"label": "Cloud",
- "href": "https://space.langbot.app/cloud?language=en"
+ "href": "https://space.langbot.app/cloud?language=en",
+ "icon": "cloud"
},
{
"label": "Extensions",
- "href": "https://space.langbot.app/market?language=en"
+ "href": "https://space.langbot.app/market?language=en",
+ "icon": "blocks"
},
{
"label": "Blog",
- "href": "https://langbot.app/en/blog"
+ "href": "https://langbot.app/en/blog",
+ "icon": "newspaper"
},
{
"label": "Roadmap",
- "href": "https://langbot.app/en/roadmap"
+ "href": "https://langbot.app/en/roadmap",
+ "icon": "map"
}
],
"primary": {
"type": "button",
"label": "GitHub",
- "href": "https://github.com/langbot-app/LangBot"
+ "href": "https://github.com/langbot-app/LangBot",
+ "icon": "github"
}
}
},
@@ -1091,31 +1093,32 @@
],
"navbar": {
"links": [
- {
- "label": "首页",
- "href": "https://langbot.app/zh"
- },
{
"label": "云服务",
- "href": "https://space.langbot.app/cloud?language=zh"
+ "href": "https://space.langbot.app/cloud?language=zh",
+ "icon": "cloud"
},
{
"label": "扩展",
- "href": "https://space.langbot.app/market?language=zh"
+ "href": "https://space.langbot.app/market?language=zh",
+ "icon": "blocks"
},
{
"label": "博客",
- "href": "https://langbot.app/zh/blog"
+ "href": "https://langbot.app/zh/blog",
+ "icon": "newspaper"
},
{
"label": "路线图",
- "href": "https://langbot.app/zh/roadmap"
+ "href": "https://langbot.app/zh/roadmap",
+ "icon": "map"
}
],
"primary": {
"type": "button",
"label": "GitHub",
- "href": "https://github.com/langbot-app/LangBot"
+ "href": "https://github.com/langbot-app/LangBot",
+ "icon": "github"
}
}
},
@@ -1377,31 +1380,32 @@
],
"navbar": {
"links": [
- {
- "label": "ホーム",
- "href": "https://langbot.app/ja"
- },
{
"label": "クラウド",
- "href": "https://space.langbot.app/cloud?language=ja"
+ "href": "https://space.langbot.app/cloud?language=ja",
+ "icon": "cloud"
},
{
"label": "拡張機能",
- "href": "https://space.langbot.app/market?language=ja"
+ "href": "https://space.langbot.app/market?language=ja",
+ "icon": "blocks"
},
{
"label": "ブログ",
- "href": "https://langbot.app/ja/blog"
+ "href": "https://langbot.app/ja/blog",
+ "icon": "newspaper"
},
{
"label": "ロードマップ",
- "href": "https://langbot.app/ja/roadmap"
+ "href": "https://langbot.app/ja/roadmap",
+ "icon": "map"
}
],
"primary": {
"type": "button",
"label": "GitHub",
- "href": "https://github.com/langbot-app/LangBot"
+ "href": "https://github.com/langbot-app/LangBot",
+ "icon": "github"
}
}
}
diff --git a/press.config.tsx b/press.config.tsx
index 31787944b..962cad66a 100644
--- a/press.config.tsx
+++ b/press.config.tsx
@@ -9,7 +9,7 @@ import { update } from "fumadocs-core/source";
import { uiTranslations } from "fumadocs-ui/i18n";
import { defineDocs } from "fumadocs-mdx/macro";
import { createOpenAPI, type OpenAPIServer } from "fumadocs-openapi/server";
-import { Bot } from "lucide-react";
+import { Blocks, Bot, Cloud, ExternalLink, Map as MapIcon, Newspaper } from "lucide-react";
import { readFileSync, readdirSync } from "node:fs";
import path from "node:path";
@@ -204,21 +204,73 @@ function collectRouteLocales() {
const routeLocales = collectRouteLocales();
+function GithubMark(props: import("react").ComponentProps<"svg">) {
+ return ;
+}
+
+const QUICK_LINK_ICONS = {
+ blocks: Blocks,
+ cloud: Cloud,
+ github: GithubMark,
+ map: MapIcon,
+ newspaper: Newspaper,
+} as const;
+
+type QuickLinkIcon = keyof typeof QUICK_LINK_ICONS;
+type ConfiguredNavbarLink = {
+ href: string;
+ icon?: QuickLinkIcon;
+ label?: string;
+};
+type ConfiguredNavbar = {
+ links?: ConfiguredNavbarLink[];
+ primary?: ConfiguredNavbarLink & { type?: string };
+};
+
+function quickLinkIcon(name: QuickLinkIcon | undefined) {
+ if (!name) return undefined;
+ const Icon = QUICK_LINK_ICONS[name];
+ return ;
+}
+
+function quickLinkText(text: string) {
+ return
+ {text}
+
+ ;
+}
+
function localizedNavbar(lang: string | undefined) {
const locale = LOCALES.includes(lang as (typeof LOCALES)[number]) ? lang as (typeof LOCALES)[number] : "en";
const language = mintlifyDocs.navigation.languages?.find(
(entry) => entry.language === MINTLIFY_LOCALE[locale],
);
- const navbar = language?.navbar ?? mintlifyDocs.navbar;
+ const navbar = (language?.navbar ?? mintlifyDocs.navbar) as ConfiguredNavbar | undefined;
+ const linkItem = (link: ConfiguredNavbarLink) => ({
+ text: quickLinkText(link.label ?? link.href),
+ url: link.href,
+ icon: quickLinkIcon(link.icon),
+ external: true,
+ });
return [
- ...(navbar?.links ?? []).map((link) => ({ text: link.label ?? link.href, url: link.href })),
- ...(navbar?.primary ? [{
- type: "button" as const,
- text: navbar.primary.label ?? navbar.primary.href,
- url: navbar.primary.href,
- }] : []),
+ ...(navbar?.links ?? []).map(linkItem),
+ ...(navbar?.primary ? [{ ...linkItem(navbar.primary), type: "button" as const }] : []),
];
}
+
+function docsBrand() {
+ return
+
+ LangBot Docs
+ ;
+}
const enOpenAPI = createOpenAPI({ input: ["openapi/service-api-en.json"] });
const zhOpenAPI = createOpenAPI({ input: ["openapi/service-api-zh.json"] });
const jaOpenAPI = createOpenAPI({ input: ["openapi/service-api-ja.json"] });
@@ -306,9 +358,16 @@ export default defineConfig({
},
i18n,
translations,
- defaultLayoutProps: ({ lang }) => ({
- links: localizedNavbar(lang),
- }),
+ defaultLayoutProps: ({ lang }) => {
+ const locale = LOCALES.includes(lang as (typeof LOCALES)[number]) ? lang as (typeof LOCALES)[number] : "en";
+ return {
+ links: localizedNavbar(locale),
+ nav: {
+ title: docsBrand(),
+ url: `/${locale}/insight/guide`,
+ },
+ };
+ },
meta: {
page: (page) => {
const locale = page.locale as (typeof LOCALES)[number];
diff --git a/tests/fumapress-static-build.test.mjs b/tests/fumapress-static-build.test.mjs
index a74232e2c..e0aa16ee8 100644
--- a/tests/fumapress-static-build.test.mjs
+++ b/tests/fumapress-static-build.test.mjs
@@ -241,18 +241,24 @@ function extractHeadLinks(html, rel) {
test("rendered navbar and documentation tree use each locale's docs.json labels", async () => {
const expected = {
- en: ["Home", "https://langbot.app/en", "Roadmap", "https://langbot.app/en/roadmap", "Guides", "Quick Start", "Installation", "Developers", "Articles", "API Reference"],
- zh: ["首页", "https://langbot.app/zh", "路线图", "https://langbot.app/zh/roadmap", "指南", "快速开始", "安装部署", "开发者", "文章", "API 参考"],
- ja: ["ホーム", "https://langbot.app/ja", "ロードマップ", "https://langbot.app/ja/roadmap", "ガイド", "クイックスタート", "インストール", "開発者", "記事", "API リファレンス"],
+ en: ["Roadmap", "https://langbot.app/en/roadmap", "Guides", "Quick Start", "Installation", "Developers", "Articles", "API Reference"],
+ zh: ["路线图", "https://langbot.app/zh/roadmap", "指南", "快速开始", "安装部署", "开发者", "文章", "API 参考"],
+ ja: ["ロードマップ", "https://langbot.app/ja/roadmap", "ガイド", "クイックスタート", "インストール", "開発者", "記事", "API リファレンス"],
+ };
+ const removedHomeLinks = {
+ en: "https://langbot.app/en",
+ zh: "https://langbot.app/zh",
+ ja: "https://langbot.app/ja",
};
for (const locale of locales) {
const html = await readFile(path.join(publicRoot, locale, "insight/guide/index.html"), "utf8");
for (const value of expected[locale]) assert.ok(html.includes(value), `${locale} navbar missing ${value}`);
+ assert.ok(!html.includes(`href="${removedHomeLinks[locale]}"`), `${locale} navbar still includes Home`);
for (const languageName of ["English", "简体中文", "日本語"]) {
assert.ok(html.includes(languageName), `${locale} language selector missing ${languageName}`);
}
for (const other of locales.filter((item) => item !== locale)) {
- assert.ok(!html.includes(expected[other][1]), `${locale} navbar includes ${other} home link`);
+ assert.ok(!html.includes(expected[other][1]), `${locale} navbar includes ${other} roadmap link`);
}
}
});
diff --git a/tests/seo.test.mjs b/tests/seo.test.mjs
index 45328ad72..700d019a9 100644
--- a/tests/seo.test.mjs
+++ b/tests/seo.test.mjs
@@ -39,15 +39,15 @@ test("navbar is localized and links to locale-aware product pages", async () =>
);
const expected = {
en: {
- labels: ["Home", "Cloud", "Extensions", "Blog", "Roadmap"],
+ labels: ["Cloud", "Extensions", "Blog", "Roadmap"],
roadmap: "https://langbot.app/en/roadmap",
},
cn: {
- labels: ["首页", "云服务", "扩展", "博客", "路线图"],
+ labels: ["云服务", "扩展", "博客", "路线图"],
roadmap: "https://langbot.app/zh/roadmap",
},
jp: {
- labels: ["ホーム", "クラウド", "拡張機能", "ブログ", "ロードマップ"],
+ labels: ["クラウド", "拡張機能", "ブログ", "ロードマップ"],
roadmap: "https://langbot.app/ja/roadmap",
},
};
@@ -58,14 +58,29 @@ test("navbar is localized and links to locale-aware product pages", async () =>
navbar.links.map((link) => link.label),
expected[language].labels,
);
+ assert.deepEqual(
+ navbar.links.map((link) => link.icon),
+ ["cloud", "blocks", "newspaper", "map"],
+ );
assert.equal(navbar.links.at(-1).href, expected[language].roadmap);
assert.equal(navbar.primary.type, "button");
assert.equal(navbar.primary.label, "GitHub");
+ assert.equal(navbar.primary.icon, "github");
assert.equal(
navbar.primary.href,
"https://github.com/langbot-app/LangBot",
);
}
+
+ assert.deepEqual(
+ docs.navbar.links.map((link) => link.label),
+ expected.en.labels,
+ );
+ assert.deepEqual(
+ docs.navbar.links.map((link) => link.icon),
+ ["cloud", "blocks", "newspaper", "map"],
+ );
+ assert.equal(docs.navbar.primary.icon, "github");
});
test("custom robots policy is served from the Mintlify project root", async () => {