blob: 2a29308f75b940cb598fde30e13cea0f728e0779 [file]
const themes = require('prism-react-renderer').themes;
const versionsPlugin = require('./config/versions-plugin');
const VERSIONS = require('./versions.json');
const { markdownBoldPlugin } = require('./config/markdown-bold-plugin');
const { DEFAULT_VERSION } = require('./src/constant/version');
const { ssrTemplate } = require('./config/ssrTemplate');
const customDocusaurusPlugin = require('./config/custom-docusaurus-plugin');
const REDIRECTS_4X = require('./config/redirects-4.x.json');
// Group every static in-site redirect by its target path so we can drive it
// through @docusaurus/plugin-client-redirects' `createRedirects` callback.
// The callback runs once per locale build with `existingPath` set to the
// actual routes in that build — so each entry only fires when its target
// truly exists. Plain `redirects:` array entries can't do that: the plugin
// validates the whole array against the current locale's path list, which
// rejects cross-locale targets (e.g. /zh-CN/... during an en-only build).
function buildRedirectIndex() {
const index = {};
const add = (to, ...froms) => {
(index[to] = index[to] || []).push(...froms);
};
// /docs and /zh-CN/docs land on the default stable version's entry doc.
// `lastVersion: '4.x'` makes 4.x the stable version but its `path: '4.x'`
// keeps it under /docs/4.x/, so the bare /docs route has no generated
// page without this redirect.
add('/docs/4.x/getting-started/what-is-apache-doris', '/docs');
add('/zh-CN/docs/4.x/getting-started/what-is-apache-doris', '/zh-CN/docs');
// Decommissioned standalone pages whose content moved into the
// homepage/why-doris/download flows.
add('/why-doris/users', '/users');
add('/zh-CN/why-doris/users', '/zh-CN/users');
add('/download', '/download-next');
add('/zh-CN/download', '/zh-CN/download-next');
// /ecosystem/* was retired; its closest spiritual home is the Dev tree's
// Data Integration intro, which catalogs the same connector/tool families
// the old /ecosystem/ pages did.
add(
'/docs/dev/connection-integration/data-integration/intro',
'/ecosystem',
'/ecosystem/cluster-management',
'/ecosystem/connectors',
'/ecosystem/data-loading',
'/ecosystem/data-migration',
'/ecosystem/distributions-and-packaging',
);
add(
'/zh-CN/docs/dev/connection-integration/data-integration/intro',
'/zh-CN/ecosystem',
'/zh-CN/ecosystem/cluster-management',
'/zh-CN/ecosystem/connectors',
'/zh-CN/ecosystem/data-loading',
'/zh-CN/ecosystem/data-migration',
'/zh-CN/ecosystem/distributions-and-packaging',
);
// Old 4.x slugs that have no 1:1 counterpart in the new 4.x tree
// (which was reseeded from Dev). Generated by
// scripts/migrate-4.x/build-redirects.py from the diff between
// old-slugs.txt and new-slugs.txt.
for (const { from, to } of REDIRECTS_4X) {
add(to, from);
}
return index;
}
const REDIRECT_INDEX = buildRedirectIndex();
// Allow filtering doc versions via environment variable.
// Usage: DOCS_VERSIONS="current,4.x" yarn docusaurus build
// This uses Docusaurus's native onlyIncludeVersions option
// instead of modifying versions.json.
const ONLY_VERSIONS = process.env.DOCS_VERSIONS
? process.env.DOCS_VERSIONS.split(',').map(v => v.trim()).filter(Boolean)
: null;
// Landing-only dev mode: when working on src/components/home-next or
// use-cases-next, no docs/blog/search routes need to load. Setting
// LANDING_ONLY=true disables every heavy content plugin, which drops
// `yarn start` peak memory from ~20GB to ~1-2GB. Individual SKIP_* env
// vars allow finer-grained control.
const LANDING_ONLY = process.env.LANDING_ONLY === 'true';
const SKIP_DOCS = LANDING_ONLY || process.env.SKIP_DOCS === 'true';
const SKIP_BLOG = LANDING_ONLY || process.env.SKIP_BLOG === 'true';
const SKIP_COMMUNITY = LANDING_ONLY || process.env.SKIP_COMMUNITY === 'true';
const SKIP_RELEASES = LANDING_ONLY || process.env.SKIP_RELEASES === 'true';
const SKIP_SEARCH = LANDING_ONLY || process.env.SKIP_SEARCH === 'true';
const LINK_BEHAVIOR_VALUES = new Set(['ignore', 'log', 'warn', 'throw']);
function getBrokenLinkBehavior(envName, fallback) {
const value = process.env[envName];
return LINK_BEHAVIOR_VALUES.has(value) ? value : fallback;
}
const DEFAULT_BROKEN_LINK_BEHAVIOR = 'warn';
const lightCodeTheme = themes.oneLight;
const logoImg = '/images/logo-doris.svg';
function getDocsVersions() {
const result = {
current: {
label: 'Dev',
path: 'dev',
banner: 'unreleased',
},
};
VERSIONS.map(version => {
result[version] = {
banner: 'none',
};
if (version === DEFAULT_VERSION) {
result[version].label = DEFAULT_VERSION;
result[version].path = DEFAULT_VERSION;
} else {
result[version].badge = false;
}
});
return result;
}
function getLatestVersion() {
return VERSIONS.includes(DEFAULT_VERSION) ? DEFAULT_VERSION : VERSIONS[0];
}
/** @type {import('@docusaurus/types').Config} */
const config = {
title: 'Apache Doris',
titleDelimiter: '-',
tagline: 'Apache Doris',
url: 'https://doris.apache.org',
baseUrl: '/',
onBrokenLinks: getBrokenLinkBehavior('DORIS_DOCUSAURUS_BROKEN_LINKS', DEFAULT_BROKEN_LINK_BEHAVIOR),
onBrokenMarkdownLinks: getBrokenLinkBehavior('DORIS_DOCUSAURUS_BROKEN_MARKDOWN_LINKS', DEFAULT_BROKEN_LINK_BEHAVIOR),
favicon: 'images/favicon.ico',
organizationName: 'Apache',
trailingSlash: false,
markdown: {
format: 'detect',
},
trailingSlash: true,
i18n: {
defaultLocale: 'en',
locales: ['en', 'zh-CN', 'ja'],
localeConfigs: {
en: {
label: 'English',
htmlLang: 'en-US',
},
'zh-CN': {
label: '中文',
htmlLang: 'zh-Hans-CN',
},
ja: {
label: '日本語',
htmlLang: 'ja-JP',
},
},
},
scripts: ['/js/custom-script.js',
{
async: true,
src: 'https://widget.kapa.ai/kapa-widget.bundle.js',
'data-website-id': 'a5fb90df-217a-4097-95c0-80490220314b',
'data-modal-title': 'Apache Doris AI',
'data-project-name': 'Apache Doris Website',
'data-button-hide': "true",
'data-modal-override-open-selector': "#navbar-ask-ai-btn",
'data-project-logo': 'https://cdn.selectdb.com/static/doris_1_3c42247c63.png',
'data-modal-image': 'https://cdn.selectdb.com/static/doris_logo_cc5a30d886.png',
'data-project-color': '#11A679',
'data-modal-disclaimer': 'This is a custom LLM with access to all [Doris documentation](https://doris.apache.org/docs/4.x/gettingStarted/what-is-apache-doris).',
'data-consent-required': true,
'data-consent-screen-disclaimer': "By clicking "I agree, let's chat", you consent to the use of the AI assistant in accordance with kapa.ai's [Privacy Policy](https://www.kapa.ai/content/privacy-policy). This service uses reCAPTCHA, which requires your consent to Google's [Privacy Policy](https://policies.google.com/privacy) and [Terms of Service](https://policies.google.com/terms). By proceeding, you explicitly agree to both kapa.ai's and Google's privacy policies.",
'data-user-analytics-cookie-enabled': false,
'data-bot-protection-mechanism': "hcaptcha"
}
],
stylesheets: [
{
href: '/css/katex.min.css',
type: 'text/css',
},
],
projectName: 'apache/doris-website', // Usually your repo name.
customFields: {},
future: {
experimental_faster: true,
},
plugins: [
'docusaurus-plugin-sass',
'docusaurus-plugin-matomo',
// Use custom blog plugin
versionsPlugin,
SKIP_COMMUNITY ? null : [
'content-docs',
/** @type {import('@docusaurus/plugin-content-docs').Options} */
({
id: 'community',
path: 'community',
routeBasePath: '/community',
sidebarPath: require.resolve('./sidebarsCommunity.json'),
}),
],
SKIP_RELEASES ? null : [
'content-docs',
/** @type {import('@docusaurus/plugin-content-docs').Options} */
({
id: 'releases',
path: 'releasenotes',
routeBasePath: '/releases',
sidebarPath: require.resolve('./sidebarsReleases.json'),
}),
],
process.env.NODE_ENV === 'development' ? null : customDocusaurusPlugin,
async function tailwindcssPlugin(context, options) {
return {
name: 'docusaurus-tailwindcss',
configurePostCss(postcssOptions) {
// Appends TailwindCSS and AutoPrefixer
postcssOptions.plugins.push(require('tailwindcss'));
postcssOptions.plugins.push(require('autoprefixer'));
return postcssOptions;
},
};
},
[
'@docusaurus/plugin-client-redirects',
{
fromExtensions: ['html', 'htm'],
redirects: [
// Only external-target redirects belong here. Anything
// pointing at an in-site path must go through
// createRedirects below, otherwise plugin-client-redirects
// rejects cross-locale entries during single-locale builds.
{
from: '/slack',
to: 'https://join.slack.com/t/apachedoriscommunity/shared_invite/zt-3wvgezmm8-lh5XRaLg0~9AF44ojdIBfw'
},
],
createRedirects(existingPath) {
const redirects = [];
// Static redirects indexed by target. Trim trailing slash
// for the lookup since Docusaurus' trailingSlash:true
// gives us paths like /docs/4.x/foo/.
const normalized = existingPath.replace(/\/$/, '');
if (REDIRECT_INDEX[normalized]) {
redirects.push(...REDIRECT_INDEX[normalized]);
}
// Legacy `/gettingStarted/what-is-new` slug → renamed to
// `/gettingStarted/what-is-apache-doris`. Register the old
// path as a redirect for any existing version that has the
// new slug.
if (existingPath.includes('/gettingStarted/what-is-apache-doris')) {
redirects.push(
existingPath.replace(
'/gettingStarted/what-is-apache-doris',
'/gettingStarted/what-is-new',
),
);
}
// 3.x version-prefix variants: legacy URLs sometimes used
// /docs/3.0/ (the dot release) or omitted the version
// segment entirely. Map both shapes onto the canonical
// /docs/3.x/ path.
if (existingPath.startsWith('/docs/3.x/')) {
redirects.push(
existingPath.replace('/docs/3.x/', '/docs/'),
existingPath.replace('/docs/3.x/', '/docs/3.0/'),
);
}
// Redirect old versioned releasenotes URLs to new /releases/ paths
// e.g. /docs/4.x/releasenotes/v4.0/release-4.0.5 -> /releases/v4.0/release-4.0.5
if (existingPath.startsWith('/releases/')) {
const releasePath = existingPath.replace('/releases/', '');
const oldVersionPrefixes = ['4.x', '3.x', '2.1', '2.0', '1.2', '4.0', '3.1', '3.0', 'dev'];
for (const ver of oldVersionPrefixes) {
redirects.push(`/docs/${ver}/releasenotes/${releasePath}`);
}
}
return redirects.length > 0 ? redirects : undefined;
},
},
],
],
presets: [
[
'classic',
/** @type {import('@docusaurus/preset-classic').Options} */
({
docs: SKIP_DOCS ? false : {
includeCurrentVersion: true,
sidebarPath: require.resolve('./sidebars.ts'),
...(ONLY_VERSIONS && { onlyIncludeVersions: ONLY_VERSIONS }),
// When filtering versions, lastVersion must be in the
// included list. Fall back to the first included version.
lastVersion: ONLY_VERSIONS && !ONLY_VERSIONS.includes(getLatestVersion())
? ONLY_VERSIONS[0]
: getLatestVersion(),
versions: getDocsVersions(),
// editUrl: ({ locale, versionDocsDirPath, docPath }) => {
// return `https://github.com/apache/doris-website/edit/master/docs/${locale}/docs/${docPath}`;
// // if (versionDocsDirPath === 'versioned_docs/version-dev') {
// // return `https://github.com/apache/doris-website/edit/master/docs/${locale}/docs/${docPath}`;
// // }
// },
showLastUpdateAuthor: false,
showLastUpdateTime: false,
remarkPlugins: [markdownBoldPlugin, require('remark-math')],
rehypePlugins: [
[
require('rehype-katex'),
{
strict: process.env.CI === 'true' || process.env.GITHUB_ACTIONS === 'true' ? false : 'warn',
}
]
]
},
blog: SKIP_BLOG ? false : {
blogTitle: 'Apache Doris - Blog | Latest news and events ',
blogDescription:
'Explore how Doris empower lakehouse, adhoc analysis, customer-facing analysis and various scenarios',
postsPerPage: 'ALL',
blogSidebarCount: 0,
showReadingTime: false,
onUntruncatedBlogPosts: 'ignore',
onInlineAuthors: 'ignore',
},
theme: {
customCss: require.resolve('./src/scss/custom.scss'),
},
sitemap: {
changefreq: 'weekly',
priority: 0.5,
filename: 'sitemap.xml',
createSitemapItems: async params => {
const { defaultCreateSitemapItems, ...rest } = params;
const items = await defaultCreateSitemapItems(rest);
const filteredItems = items.filter(item => {
const pathname = new URL(item.url).pathname.replace(/\/+$/, '');
if (['/search', '/ja/search', '/zh-CN/search'].includes(pathname)) return false;
return true;
});
for (let item of filteredItems) {
if (item.url.includes('docs')) {
item.changefreq = 'daily';
item.priority = 0.8;
}
if (item.url.includes('docs/1.2')) {
item.priority = 0.2;
}
}
return filteredItems;
},
},
}),
],
],
themes: SKIP_SEARCH ? [] : [
[
'@yang1666204/docusaurus-search-local',
{
hashed: true,
language: ['en', 'zh', 'ja'],
highlightSearchTermsOnTargetPage: true,
// indexPages: true,
indexDocs: true,
docsRouteBasePath: ['docs', 'ja/docs', 'zh-CN/docs'],
indexBlog: false,
explicitSearchResultPath: true,
searchBarShortcut: true,
searchBarShortcutHint: true,
searchResultLimits: 100,
searchContextByPaths: ['docs'],
useAllContextsWithNoSearchContext: false,
ignoreFiles: [/^docs\/(?:[^/]+\/)?key-features\//],
},
],
],
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
matomo: {
matomoUrl: 'https://analytics.apache.org/',
siteId: '43',
phpLoader: 'matomo.php',
jsLoader: 'matomo.js',
},
// NavbarNext renders the actual top navigation (driven by the
// home-next code, not themeConfig). This stub stays only because
// Docusaurus' theme validator wants the key present.
navbar: {
items: [],
},
footer: {
links: [
{
title: 'ASF',
items: [
{
label: 'Foundation',
href: 'https://www.apache.org/',
},
{
label: 'License',
href: 'https://www.apache.org/licenses/',
},
{
label: 'Events',
href: 'https://www.apache.org/events/current-event',
},
{
label: 'Sponsorship',
href: 'https://www.apache.org/foundation/sponsorship.html',
},
{
label: 'Privacy',
href: 'https://privacy.apache.org/policies/privacy-policy-public.html',
},
{
label: 'Security',
href: 'https://www.apache.org/security/',
},
{
label: 'Thanks',
href: 'https://www.apache.org/foundation/thanks.html',
},
],
},
{
title: 'Resources',
items: [
{
label: 'Download',
href: '/download',
},
// {
// label: 'Docs',
// href: '/docs/get-starting/quick-start',
// },
{
label: 'Blog',
href: '/blog',
},
],
},
{
title: 'Community',
items: [
{
label: 'How to contribute',
href: '/community/how-to-contribute/contribute-to-doris',
},
{
label: 'Source code',
href: 'https://github.com/apache/doris/',
},
{
label: 'Doris team',
href: '/community/team',
},
{
label: 'Roadmap',
href: 'https://github.com/apache/doris/issues/60036',
},
{
label: 'Improvement proposal',
href: 'https://cwiki.apache.org/confluence/display/DORIS/Doris+Improvement+Proposals',
},
],
},
],
logo: {
alt: '',
src: '/images/asf_logo_apache.svg',
},
copyright: `Copyright © ${new Date().getFullYear()} The Apache Software Foundation,Licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0" target="_blank">Apache License, Version 2.0</a>. Apache, Doris, Apache Doris, the Apache feather logo and the Apache Doris logo are trademarks of The Apache Software Foundation.`,
},
docs: {
sidebar: {
autoCollapseCategories: true,
},
},
prism: {
theme: lightCodeTheme,
additionalLanguages: ['java'],
},
colorMode: {
disableSwitch: true,
},
// metadata: [
// {
// name: 'viewport',
// content:
// 'width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no',
// },
// ],s
}),
ssrTemplate
};
module.exports = config;