Files
homarr/apps/docs/docusaurus.config.ts
T
Thomas 45d8bc9443 feat: add the community-funded Homarr assistant provider (#6563)
* Add Homarr provider proxy foundation

* Complete Homarr provider integration

* Harden Homarr provider integration

* Address Homarr provider review feedback

* Address CodeRabbit provider feedback

* Localize provider errors

* Handle provider activity load failures

* docs: improve workshop and homepage

* Harden Homarr provider limits

* fix: harden the Homarr provider

* fix: address provider review feedback

* fix: clarify provider request accounting

* feat: complete the Homarr provider endpoint

* fix: terminate invalid provider streams
2026-08-14 11:32:11 +02:00

423 lines
12 KiB
TypeScript

import type * as Preset from "@docusaurus/preset-classic";
import type { Config } from "@docusaurus/types";
import { themes as prismThemes } from "prism-react-renderer";
import { resolveHomarrUrlConfig } from "@homarr/workshop/schema";
const a11yEmoji = require("@fec/remark-a11y-emoji");
const deprecatedWorkshopUrl = process.env.WORKSHOP_URL;
if (deprecatedWorkshopUrl && !process.env.WORKSHOP_API_URL) {
console.warn("WORKSHOP_URL is deprecated; use WORKSHOP_API_URL instead.");
}
const publicUrls = resolveHomarrUrlConfig({
homarrWebsiteUrl: process.env.HOMARR_WEBSITE_URL,
workshopApiUrl: process.env.WORKSHOP_API_URL ?? deprecatedWorkshopUrl,
workshopWebUrl: process.env.WORKSHOP_WEB_URL,
});
const config: Config = {
title: "Homarr documentation",
tagline: "A simple yet powerful dashboard for your server.",
url: publicUrls.homarrWebsiteUrl,
baseUrl: "/",
trailingSlash: undefined,
favicon: "img/logo.png",
organizationName: "homarr-labs",
projectName: "homarr",
customFields: {
workshopUrl: publicUrls.workshopApiUrl,
workshopWebUrl: publicUrls.workshopWebUrl,
},
scripts: [{ src: "/workshop-runtime-config.js" }],
i18n: {
defaultLocale: "en",
locales: ["en"],
},
onBrokenLinks: "throw",
onBrokenAnchors: "throw",
onDuplicateRoutes: "throw",
future: {
v4: {
removeLegacyPostBuildHeadAttribute: true,
useCssCascadeLayers: true,
siteStorageNamespacing: true,
fasterByDefault: true,
mdx1CompatDisabledByDefault: false,
},
faster: {
swcHtmlMinimizer: false,
},
},
markdown: {
mermaid: true,
format: "detect",
hooks: {
onBrokenMarkdownLinks: "throw",
},
},
themes: ["@docusaurus/theme-mermaid"],
presets: [
[
"classic",
{
docs: {
sidebarPath: require.resolve("./sidebars.js"),
editUrl: ({ docPath }) => `https://github.com/homarr-labs/homarr/edit/dev/apps/docs/docs/${docPath}`,
remarkPlugins: [a11yEmoji],
exclude: [],
showLastUpdateAuthor: false,
showLastUpdateTime: false,
},
blog: {
showReadingTime: true,
// Please change this to your repo.
// Remove this to remove the "edit this page" links.
editUrl: "https://github.com/homarr-labs/homarr/edit/dev/apps/docs",
authorsMapPath: "authors.yml",
},
theme: {
customCss: require.resolve("./src/css/custom.css"),
},
sitemap: {
changefreq: "weekly",
priority: 0.5,
ignorePatterns: ["/tags/**", "/docs/category/**"],
filename: "sitemap.xml",
createSitemapItems: async ({ routes, siteConfig, defaultCreateSitemapItems }) => {
const items = await defaultCreateSitemapItems({ routes, siteConfig });
return items.map((item) => {
const path = new URL(item.url).pathname;
if (path === "/" || path === "") {
return { ...item, priority: 1.0, changefreq: "weekly" };
}
if (path.startsWith("/docs/")) {
return { ...item, priority: 0.7, changefreq: "monthly" };
}
if (path.startsWith("/blog/")) {
return { ...item, priority: 0.3, changefreq: "never" };
}
if (path.startsWith("/about-us")) {
return { ...item, priority: 0.4, changefreq: "yearly" };
}
return item;
});
},
},
} satisfies Preset.Options,
],
],
themeConfig: {
navbar: {
title: "Homarr",
logo: {
alt: "Homarr Logo",
src: "img/logo.png",
},
items: [
{
label: "Documentation",
type: "doc",
position: "left",
docId: "getting-started/index",
},
{
label: "Blog",
position: "left",
to: "/blog",
className: "navbar-item--secondary",
},
{
label: "Workshop",
position: "left",
to: "/workshop",
},
{
label: "About us",
position: "left",
to: "/about-us",
className: "navbar-item--collapse-first",
},
{
to: "https://demo.homarr.dev/",
label: "Demo",
position: "right",
className: "navbar-item--secondary",
},
{
to: "https://opencollective.com/homarr",
label: "💴 Donate",
position: "right",
className: "navbar-item--collapse-first",
},
{
type: "dropdown",
label: "Community",
position: "right",
items: [
{
to: "https://discord.com/invite/aCsmEV5RgA",
label: "Discord",
},
{
to: "https://github.com/homarr-labs/homarr",
label: "GitHub",
},
{
to: "https://www.answeroverflow.com/c/972958686051962910",
label: "Answer Overflow",
},
{
to: "https://crowdin.com/project/homarr_labs",
label: "Community translations (Crowdin)",
},
{
to: "https://www.reddit.com/r/homarr/",
label: "Reddit",
},
{
to: "https://opencollective.com/homarr",
label: "OpenCollective",
},
{
to: "https://x.com/homarr_labs",
label: "X / Twitter",
},
],
},
{
type: "search",
position: "right",
},
],
hideOnScroll: false,
},
algolia: {
appId: "N69WSPZTID",
apiKey: "b2b00f4ed8ca3dc87b5d211c55121416",
indexName: "Docusaurus",
contextualSearch: false,
searchPagePath: "search",
insights: false,
replaceSearchResultPathname: {
from: "/docs/(next|\\d+(?:\\.\\d+)*)/",
to: "/docs/",
},
},
footer: {
links: [
{
title: "Documentation",
items: [
{
label: "Installation",
to: "/docs/category/getting-started",
},
],
},
{
title: "Community",
items: [
{
label: "Discord",
to: "https://discord.com/invite/aCsmEV5RgA",
},
{
label: "GitHub",
to: "https://github.com/homarr-labs/homarr",
},
{
label: "Donate",
to: "https://opencollective.com/homarr",
},
],
},
{
title: "More",
items: [
{
label: "Blog",
to: "/blog",
},
{
label: "About us",
to: "/about-us",
},
],
},
],
logo: {
alt: "Homarr home",
src: "img/logo.svg",
href: "/",
width: 86,
height: 58,
},
copyright: `
<div class="footer__brand-copy">
<strong class="footer__brand-name">Homarr</strong>
<span class="footer__brand-tagline">Your dashboard for the services you run.</span>
<span class="copyright_text">© ${new Date().getFullYear()} Homarr · <a href="/docs/community/license">License</a></span>
</div>
`,
},
prism: {
theme: prismThemes.github,
darkTheme: prismThemes.dracula,
defaultLanguage: "bash",
},
colorMode: {
defaultMode: "dark",
respectPrefersColorScheme: true,
},
metadata: [
{
name: "keywords",
content: "Homarr, Dashboard, Selfhosted, Hosting, Modules, Open-Source",
},
],
zoom: {
selector: ".markdown :not(em) > img",
background: {
light: "rgb(255, 255, 255)",
dark: "rgb(50, 50, 50)",
},
config: {
// options you can specify via https://github.com/francoischalifour/medium-zoom#usage
margin: 80,
},
},
tableOfContents: {
minHeadingLevel: 2,
maxHeadingLevel: 4,
},
} satisfies Preset.ThemeConfig,
plugins: [
function homarrPackagesPlugin() {
return {
name: "resolve-homarr-packages",
configureWebpack(_config, isServer, { getJSLoader }) {
return {
resolve: {
symlinks: false,
alias: { "@": require("path").resolve(__dirname, "src") },
},
module: {
rules: [
{
test: /\.[jt]sx?$/iu,
include: /node_modules[\\/]@homarr/u,
use: [getJSLoader({ isServer })],
},
],
},
};
},
};
},
[
"posthog-docusaurus",
{
apiKey: "phc_pWxeD1hbl4ip02JYReX1Crjkt5DhB3dduigirHMCtFE",
appUrl: "https://hog.homarr.dev",
enableInDevelopment: true,
ui_host: "https://eu.posthog.com",
defaults: "2026-01-30",
autocapture: true,
disable_session_recording: true,
advanced_disable_feature_flags: true,
},
],
"docusaurus-plugin-image-zoom",
require.resolve("./plugins/validate-docs-coverage"),
function disableExpensiveBundlerOptimizationPlugin() {
return {
name: "disable-expensive-bundler-optimizations",
configureWebpack(_config: unknown, isServer: boolean) {
return {
optimization: {
concatenateModules: process.env.CI != null && process.env.CI !== "false" ? !isServer : false,
},
};
},
};
},
function workshopRoutesPlugin() {
return {
name: "workshop-routes",
injectHtmlTags() {
return {
headTags: [
{
tagName: "style",
innerHTML: `
#workshop-detail-route-fallback { display: none; }
html[data-workshop-detail-loading] #__docusaurus { display: none; }
html[data-workshop-detail-loading] #workshop-detail-route-fallback {
align-items: center;
background: #fff;
box-sizing: border-box;
color: #4b5563;
display: flex;
font: 500 0.875rem/1.5 "Work Sans", system-ui, sans-serif;
justify-content: center;
min-height: 100vh;
padding: 2rem;
}
@media (prefers-color-scheme: dark) {
html[data-workshop-detail-loading] #workshop-detail-route-fallback {
background: #18191a;
color: #d1d5db;
}
}`,
},
{
tagName: "script",
innerHTML: `(function () {
var match = window.location.pathname.match(/^\\/workshop\\/([^/]+)\\/?$/);
if (match && match[1] !== "admin") {
document.documentElement.setAttribute("data-workshop-detail-loading", "");
}
})();`,
},
],
preBodyTags: [
{
tagName: "div",
attributes: {
id: "workshop-detail-route-fallback",
role: "status",
"aria-live": "polite",
},
innerHTML: "Loading Workshop…",
},
],
};
},
async contentLoaded({ actions }) {
actions.addRoute({
path: "/workshop/:id",
component: "@site/src/components/workshop/WorkshopDetailRoutePage",
exact: true,
priority: -1,
});
},
};
},
async function tailwindCssPlugin() {
return {
name: "docusaurus-tailwindcss",
configurePostCss(postcssOptions) {
postcssOptions.plugins.push(require("@tailwindcss/postcss"));
return postcssOptions;
},
};
},
],
};
export default config;