| 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; |