diff --git a/packages/docusaurus-plugin-content-blog/index.js b/packages/docusaurus-plugin-content-blog/index.js index c632f8582a..acbb0e2f6e 100644 --- a/packages/docusaurus-plugin-content-blog/index.js +++ b/packages/docusaurus-plugin-content-blog/index.js @@ -10,12 +10,13 @@ const path = require('path'); const fs = require('fs-extra'); const {parse, idx, normalizeUrl, generate} = require('@docusaurus/utils'); +// TODO: Use a better slugify function that doesn't rely on a specific file extension. function fileToUrl(fileName) { return fileName .replace('-', '/') .replace('-', '/') .replace('-', '/') - .replace(/\.md$/, ''); + .replace(/\.mdx?$/, ''); } const DEFAULT_OPTIONS = { @@ -42,6 +43,10 @@ class DocusaurusPluginContentBlog { return 'docusaurus-plugin-content-blog'; } + getPathsToWatch() { + return [this.contentPath]; + } + // Fetches blog contents and returns metadata for the contents. async loadContent() { const {pageCount, include, routeBasePath} = this.options; @@ -150,10 +155,6 @@ class DocusaurusPluginContentBlog { }); }); } - - getPathsToWatch() { - return [this.contentPath]; - } } module.exports = DocusaurusPluginContentBlog; diff --git a/packages/docusaurus-plugin-content-blog/package.json b/packages/docusaurus-plugin-content-blog/package.json index c4747451c1..008273e99b 100644 --- a/packages/docusaurus-plugin-content-blog/package.json +++ b/packages/docusaurus-plugin-content-blog/package.json @@ -6,7 +6,6 @@ "license": "MIT", "dependencies": { "@docusaurus/utils": "^1.0.0", - "classnames": "^2.2.6", "fs-extra": "^7.0.1", "globby": "^9.1.0" }, diff --git a/packages/docusaurus/test/load/docs/__snapshots__/sidebars.test.js.snap b/packages/docusaurus-plugin-content-docs/__tests__/__snapshots__/sidebars.test.js.snap similarity index 100% rename from packages/docusaurus/test/load/docs/__snapshots__/sidebars.test.js.snap rename to packages/docusaurus-plugin-content-docs/__tests__/__snapshots__/sidebars.test.js.snap diff --git a/packages/docusaurus/test/load/docs/index.test.js b/packages/docusaurus-plugin-content-docs/__tests__/index.test.js similarity index 64% rename from packages/docusaurus/test/load/docs/index.test.js rename to packages/docusaurus-plugin-content-docs/__tests__/index.test.js index 4580aa2c2c..46335a80e9 100644 --- a/packages/docusaurus/test/load/docs/index.test.js +++ b/packages/docusaurus-plugin-content-docs/__tests__/index.test.js @@ -7,15 +7,26 @@ import '@babel/polyfill'; import path from 'path'; -import loadDocs from '@lib/load/docs'; -import loadSetup from '../../loadSetup'; +import loadSetup from '../../docusaurus/test/loadSetup'; +import DocusaurusPluginContentDocs from '../index'; describe('loadDocs', () => { - test('simple website', async () => { - const props = await loadSetup('simple'); - const {siteDir, docsDir, env, siteConfig} = props; - const {docsMetadatas} = await loadDocs({siteDir, docsDir, env, siteConfig}); - expect(docsMetadatas.hello).toEqual({ + test.only('simple website', async () => { + const {env, siteDir, siteConfig} = await loadSetup('simple'); + const plugin = new DocusaurusPluginContentDocs( + { + path: '../docs', + }, + { + env, + siteDir, + siteConfig, + }, + ); + const {docs: docsMetadata} = await plugin.loadContent(); + const docsDir = plugin.contentPath; + + expect(docsMetadata.hello).toEqual({ category: 'Guides', id: 'hello', language: null, @@ -29,7 +40,7 @@ describe('loadDocs', () => { title: 'Hello, World !', version: null, }); - expect(docsMetadatas['foo/bar']).toEqual({ + expect(docsMetadata['foo/bar']).toEqual({ category: 'Test', id: 'foo/bar', language: null, @@ -46,10 +57,23 @@ describe('loadDocs', () => { }); test('versioned website', async () => { - const props = await loadSetup('versioned'); - const {siteDir, docsDir, versionedDir, env, siteConfig} = props; - const {docsMetadatas} = await loadDocs({siteDir, docsDir, env, siteConfig}); - expect(docsMetadatas['version-1.0.0-foo/bar']).toEqual({ + const {env, siteDir, siteConfig, versionedDir} = await loadSetup( + 'versioned', + ); + const plugin = new DocusaurusPluginContentDocs( + { + path: '../docs', + }, + { + env, + siteDir, + siteConfig, + }, + ); + const {docs: docsMetadata} = await plugin.loadContent(); + const docsDir = plugin.contentPath; + + expect(docsMetadata['version-1.0.0-foo/bar']).toEqual({ category: 'Test', id: 'version-1.0.0-foo/bar', language: null, @@ -63,7 +87,7 @@ describe('loadDocs', () => { title: 'Bar', version: '1.0.0', }); - expect(docsMetadatas['foo/bar']).toEqual({ + expect(docsMetadata['foo/bar']).toEqual({ category: 'Test', id: 'foo/bar', language: null, @@ -80,17 +104,27 @@ describe('loadDocs', () => { }); test('versioned & translated website', async () => { - const props = await loadSetup('transversioned'); const { - siteDir, - docsDir, env, + siteDir, + siteConfig, translatedDir, versionedDir, - siteConfig, - } = props; - const {docsMetadatas} = await loadDocs({siteDir, docsDir, env, siteConfig}); - expect(docsMetadatas['ko-version-1.0.0-foo/bar']).toEqual({ + } = await loadSetup('transversioned'); + const plugin = new DocusaurusPluginContentDocs( + { + path: '../docs', + }, + { + env, + siteDir, + siteConfig, + }, + ); + const {docs: docsMetadata} = await plugin.loadContent(); + const docsDir = plugin.contentPath; + + expect(docsMetadata['ko-version-1.0.0-foo/bar']).toEqual({ category: 'Test', id: 'ko-version-1.0.0-foo/bar', language: 'ko', @@ -104,7 +138,7 @@ describe('loadDocs', () => { title: 'Bar', version: '1.0.0', }); - expect(docsMetadatas['en-version-1.0.0-foo/baz']).toEqual({ + expect(docsMetadata['en-version-1.0.0-foo/baz']).toEqual({ category: 'Test', id: 'en-version-1.0.0-foo/baz', language: 'en', @@ -121,7 +155,7 @@ describe('loadDocs', () => { title: 'Baz', version: '1.0.0', }); - expect(docsMetadatas['en-hello']).toEqual({ + expect(docsMetadata['en-hello']).toEqual({ category: 'Guides', id: 'en-hello', language: 'en', @@ -138,10 +172,23 @@ describe('loadDocs', () => { }); test('translated website', async () => { - const props = await loadSetup('translated'); - const {siteDir, translatedDir, docsDir, env, siteConfig} = props; - const {docsMetadatas} = await loadDocs({siteDir, docsDir, env, siteConfig}); - expect(docsMetadatas['ko-foo/baz']).toEqual({ + const {env, siteDir, siteConfig, translatedDir} = await loadSetup( + 'translated', + ); + const plugin = new DocusaurusPluginContentDocs( + { + path: '../docs', + }, + { + env, + siteDir, + siteConfig, + }, + ); + const {docs: docsMetadata} = await plugin.loadContent(); + const docsDir = plugin.contentPath; + + expect(docsMetadata['ko-foo/baz']).toEqual({ category: 'Test', id: 'ko-foo/baz', language: 'ko', @@ -158,7 +205,7 @@ describe('loadDocs', () => { title: 'baz', version: null, }); - expect(docsMetadatas['en-foo/bar']).toEqual({ + expect(docsMetadata['en-foo/bar']).toEqual({ category: 'Test', id: 'en-foo/bar', language: 'en', @@ -175,16 +222,23 @@ describe('loadDocs', () => { }); test('versioned website with skip next release', async () => { - const props = await loadSetup('versioned'); - const {siteDir, docsDir, versionedDir, env, siteConfig} = props; - const {docsMetadatas} = await loadDocs({ - siteDir, - docsDir, - env, - siteConfig, - skipNextRelease: true, - }); - expect(docsMetadatas['version-1.0.0-foo/bar']).toEqual({ + const {env, siteDir, siteConfig, versionedDir} = await loadSetup( + 'versioned', + ); + const plugin = new DocusaurusPluginContentDocs( + { + path: '../docs', + }, + { + env, + siteDir, + siteConfig, + cliOptions: {skipNextRelease: true}, + }, + ); + const {docs: docsMetadata} = await plugin.loadContent(); + + expect(docsMetadata['version-1.0.0-foo/bar']).toEqual({ category: 'Test', id: 'version-1.0.0-foo/bar', language: null, @@ -198,6 +252,6 @@ describe('loadDocs', () => { title: 'Bar', version: '1.0.0', }); - expect(docsMetadatas['foo/bar']).toBeUndefined(); + expect(docsMetadata['foo/bar']).toBeUndefined(); }); }); diff --git a/packages/docusaurus/test/load/docs/metadata.test.js b/packages/docusaurus-plugin-content-docs/__tests__/metadata.test.js similarity index 85% rename from packages/docusaurus/test/load/docs/metadata.test.js rename to packages/docusaurus-plugin-content-docs/__tests__/metadata.test.js index fa20489b0b..8915839126 100644 --- a/packages/docusaurus/test/load/docs/metadata.test.js +++ b/packages/docusaurus-plugin-content-docs/__tests__/metadata.test.js @@ -7,8 +7,8 @@ import '@babel/polyfill'; import path from 'path'; -import processMetadata from '@lib/load/docs/metadata'; -import loadSetup from '../../loadSetup'; +import processMetadata from '../src/metadata'; +import loadSetup from '../../docusaurus/test/loadSetup'; describe('processMetadata', () => { test('normal docs', async () => { @@ -16,8 +16,22 @@ describe('processMetadata', () => { const {docsDir, env, siteConfig} = props; const sourceA = path.join('foo', 'bar.md'); const sourceB = path.join('hello.md'); - const dataA = await processMetadata(sourceA, docsDir, env, {}, siteConfig); - const dataB = await processMetadata(sourceB, docsDir, env, {}, siteConfig); + const dataA = await processMetadata( + sourceA, + docsDir, + env, + {}, + siteConfig, + 'docs', + ); + const dataB = await processMetadata( + sourceB, + docsDir, + env, + {}, + siteConfig, + 'docs', + ); expect(dataA).toEqual({ id: 'foo/bar', language: null, @@ -42,7 +56,14 @@ describe('processMetadata', () => { const props = await loadSetup('simple'); const {docsDir, env, siteConfig} = props; const source = path.join('permalink.md'); - const data = await processMetadata(source, docsDir, env, {}, siteConfig); + const data = await processMetadata( + source, + docsDir, + env, + {}, + siteConfig, + 'docs', + ); expect(data).toEqual({ id: 'permalink', language: null, @@ -68,6 +89,7 @@ describe('processMetadata', () => { env, {}, siteConfig, + 'docs', ); const dataB = await processMetadata( sourceB, @@ -75,9 +97,24 @@ describe('processMetadata', () => { env, {}, siteConfig, + 'docs', + ); + const dataC = await processMetadata( + sourceC, + docsDir, + env, + {}, + siteConfig, + 'docs', + ); + const dataD = await processMetadata( + sourceD, + docsDir, + env, + {}, + siteConfig, + 'docs', ); - const dataC = await processMetadata(sourceC, docsDir, env, {}, siteConfig); - const dataD = await processMetadata(sourceD, docsDir, env, {}, siteConfig); expect(dataA).toEqual({ id: 'version-1.0.0-foo/bar', language: null, @@ -133,6 +170,7 @@ describe('processMetadata', () => { env, {}, siteConfig, + 'docs', ); const dataB = await processMetadata( sourceB, @@ -140,6 +178,7 @@ describe('processMetadata', () => { env, {}, siteConfig, + 'docs', ); const dataC = await processMetadata( sourceC, @@ -147,6 +186,7 @@ describe('processMetadata', () => { env, {}, siteConfig, + 'docs', ); const dataD = await processMetadata( sourceD, @@ -154,15 +194,31 @@ describe('processMetadata', () => { env, {}, siteConfig, + 'docs', + ); + const dataE = await processMetadata( + sourceE, + docsDir, + env, + {}, + siteConfig, + 'docs', + ); + const dataF = await processMetadata( + sourceF, + docsDir, + env, + {}, + siteConfig, + 'docs', ); - const dataE = await processMetadata(sourceE, docsDir, env, {}, siteConfig); - const dataF = await processMetadata(sourceF, docsDir, env, {}, siteConfig); const dataG = await processMetadata( sourceG, versionedDir, env, {}, siteConfig, + 'docs', ); const dataH = await processMetadata( sourceH, @@ -170,6 +226,7 @@ describe('processMetadata', () => { env, {}, siteConfig, + 'docs', ); expect(dataA).toEqual({ id: 'ko-version-1.0.0-foo/bar', @@ -258,6 +315,7 @@ describe('processMetadata', () => { env, {}, siteConfig, + 'docs', ); const dataB = await processMetadata( sourceB, @@ -265,9 +323,24 @@ describe('processMetadata', () => { env, {}, siteConfig, + 'docs', + ); + const dataC = await processMetadata( + sourceC, + docsDir, + env, + {}, + siteConfig, + 'docs', + ); + const dataD = await processMetadata( + sourceD, + docsDir, + env, + {}, + siteConfig, + 'docs', ); - const dataC = await processMetadata(sourceC, docsDir, env, {}, siteConfig); - const dataD = await processMetadata(sourceD, docsDir, env, {}, siteConfig); expect(dataA).toEqual({ id: 'ko-foo/bar', language: 'ko', diff --git a/packages/docusaurus/test/load/docs/order.test.js b/packages/docusaurus-plugin-content-docs/__tests__/order.test.js similarity index 99% rename from packages/docusaurus/test/load/docs/order.test.js rename to packages/docusaurus-plugin-content-docs/__tests__/order.test.js index ca41a15d4f..1b5e967194 100644 --- a/packages/docusaurus/test/load/docs/order.test.js +++ b/packages/docusaurus-plugin-content-docs/__tests__/order.test.js @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import createOrder from '@lib/load/docs/order'; +import createOrder from '../src/order'; describe('createOrder', () => { test('multiple sidebars with subcategory', () => { diff --git a/packages/docusaurus/test/load/docs/sidebars.test.js b/packages/docusaurus-plugin-content-docs/__tests__/sidebars.test.js similarity index 93% rename from packages/docusaurus/test/load/docs/sidebars.test.js rename to packages/docusaurus-plugin-content-docs/__tests__/sidebars.test.js index a34e1c533c..049762a0ad 100644 --- a/packages/docusaurus/test/load/docs/sidebars.test.js +++ b/packages/docusaurus-plugin-content-docs/__tests__/sidebars.test.js @@ -6,8 +6,8 @@ */ import path from 'path'; -import loadSidebars from '@lib/load/docs/sidebars'; -import loadSetup from '../../loadSetup'; +import loadSidebars from '../src/sidebars'; +import loadSetup from '../../docusaurus/test/loadSetup'; describe('loadSidebars', () => { const fixtures = path.join(__dirname, '..', '__fixtures__'); diff --git a/packages/docusaurus-plugin-content-docs/index.js b/packages/docusaurus-plugin-content-docs/index.js new file mode 100644 index 0000000000..59e50daed6 --- /dev/null +++ b/packages/docusaurus-plugin-content-docs/index.js @@ -0,0 +1,210 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const path = require('path'); +const globby = require('globby'); +const {getSubFolder, idx, normalizeUrl} = require('@docusaurus/utils'); +const createOrder = require('./src/order'); +const loadSidebars = require('./src/sidebars'); +const processMetadata = require('./src/metadata'); + +const DEFAULT_OPTIONS = { + metadataKey: 'docsMetadata', + metadataFileName: 'docsMetadata.json', + path: 'docs', // Path to data on filesystem, relative to site dir. + routeBasePath: 'docs', // URL Route. + include: ['**/*.md', '**/*.mdx'], // Extensions to include. + // TODO: Read from props rather than hardcoded sidebar.json. + sidebar: [], // Sidebar configuration for showing a list of documentation pages. + // TODO: Settle themeing. + docLayoutComponent: '@theme/Doc', + docItemComponent: '@theme/DocBody', +}; + +class DocusaurusPluginContentDocs { + constructor(opts, context) { + this.options = {...DEFAULT_OPTIONS, ...opts}; + this.context = context; + this.contentPath = path.resolve(this.context.siteDir, this.options.path); + } + + getName() { + return 'docusaurus-plugin-content-docs'; + } + + getPathsToWatch() { + return [this.contentPath]; + } + + // Fetches blog contents and returns metadata for the contents. + async loadContent() { + const {include, routeBasePath} = this.options; + const {siteDir, env, siteConfig, cliOptions = {}} = this.context; + const {skipNextRelease} = cliOptions; + const docsDir = this.contentPath; + + // @tested - load all sidebars including versioned sidebars + const docsSidebars = loadSidebars({siteDir, env}); + + // @tested - build the docs ordering such as next, previous, category and sidebar + const order = createOrder(docsSidebars); + + // Settle versions & translations from environment. + const translationEnabled = idx(env, ['translation', 'enabled']); + const enabledLanguages = + translationEnabled && idx(env, ['translation', 'enabledLanguages']); + const enabledLangTags = + (enabledLanguages && enabledLanguages.map(lang => lang.tag)) || []; + const defaultLangTag = idx(env, ['translation', 'defaultLanguage', 'tag']); + const versioningEnabled = idx(env, ['versioning', 'enabled']); + const versions = + (versioningEnabled && idx(env, ['versioning', 'versions'])) || []; + + // Prepare metadata container. + const docs = {}; + + if (!(versioningEnabled && skipNextRelease)) { + // Metadata for default docs files. + const docsFiles = await globby(include, { + cwd: docsDir, + }); + await Promise.all( + docsFiles.map(async source => { + // Do not allow reserved version/ translated folder name in 'docs' + // e.g: 'docs/version-1.0.0/' should not be allowed as it can cause unwanted bug + const subFolder = getSubFolder( + path.resolve(docsDir, source), + docsDir, + ); + const versionsFolders = versions.map(version => `version-${version}`); + if ([...enabledLangTags, ...versionsFolders].includes(subFolder)) { + throw new Error( + `You cannot have a folder named 'docs/${subFolder}/'`, + ); + } + + const metadata = await processMetadata( + source, + docsDir, + env, + order, + siteConfig, + routeBasePath, + ); + docs[metadata.id] = metadata; + }), + ); + } + + // Metadata for non-default-language docs. + if (translationEnabled) { + const translatedDir = path.join(siteDir, 'translated_docs'); + const translatedFiles = await globby(include, { + cwd: translatedDir, + }); + await Promise.all( + translatedFiles.map(async source => { + /* + Do not process disabled & default languages folder in `translated_docs` + e.g: 'translated_docs/ja/**' should not be processed if lang 'ja' is disabled + */ + const translatedFilePath = path.resolve(translatedDir, source); + const detectedLangTag = getSubFolder( + translatedFilePath, + translatedDir, + ); + if ( + detectedLangTag === defaultLangTag || + !enabledLangTags.includes(detectedLangTag) + ) { + return; + } + + const metadata = await processMetadata( + source, + translatedDir, + env, + order, + siteConfig, + routeBasePath, + ); + docs[metadata.id] = metadata; + }), + ); + } + + // Metadata for versioned docs. + if (versioningEnabled) { + const versionedDir = path.join(siteDir, 'versioned_docs'); + const versionedFiles = await globby(include, { + cwd: versionedDir, + }); + await Promise.all( + versionedFiles.map(async source => { + const metadata = await processMetadata( + source, + versionedDir, + env, + order, + siteConfig, + routeBasePath, + ); + docs[metadata.id] = metadata; + }), + ); + } + + // Get the titles of the previous and next ids so that we can use them. + Object.keys(docs).forEach(currentID => { + const previousID = idx(docs, [currentID, 'previous']); + if (previousID) { + const previousTitle = idx(docs, [previousID, 'title']); + docs[currentID].previous_title = previousTitle || 'Previous'; + } + const nextID = idx(docs, [currentID, 'next']); + if (nextID) { + const nextTitle = idx(docs, [nextID, 'title']); + docs[currentID].next_title = nextTitle || 'Next'; + } + }); + + // Create source to metadata mapping. + const sourceToMetadata = {}; + Object.values(docs).forEach(({source, version, permalink, language}) => { + sourceToMetadata[source] = { + version, + permalink, + language, + }; + }); + + return { + docs, + docsDir, + docsSidebars, + sourceToMetadata, + }; + } + + async contentLoaded({content, actions}) { + const {docLayoutComponent, docItemComponent, routeBasePath} = this.options; + const {addRoute} = actions; + + addRoute({ + path: normalizeUrl([this.context.siteConfig.baseUrl, routeBasePath]), + component: docLayoutComponent, + routes: Object.values(content.docs).map(metadataItem => ({ + path: metadataItem.permalink, + component: docItemComponent, + metadata: metadataItem, + modules: [metadataItem.source], + })), + }); + } +} + +module.exports = DocusaurusPluginContentDocs; diff --git a/packages/docusaurus-plugin-content-docs/package.json b/packages/docusaurus-plugin-content-docs/package.json new file mode 100644 index 0000000000..b0c44989fa --- /dev/null +++ b/packages/docusaurus-plugin-content-docs/package.json @@ -0,0 +1,16 @@ +{ + "name": "@docusaurus/plugin-content-docs", + "version": "1.0.0", + "description": "Documentation plugin for Docusaurus", + "main": "index.js", + "license": "MIT", + "dependencies": { + "@babel/polyfill": "^7.4.0", + "@docusaurus/utils": "^1.0.0", + "fs-extra": "^7.0.1", + "globby": "^9.1.0" + }, + "peerDependencies": { + "@docusaurus/core": "^2.0.0" + } +} diff --git a/packages/docusaurus/lib/load/docs/metadata.js b/packages/docusaurus-plugin-content-docs/src/metadata.js similarity index 97% rename from packages/docusaurus/lib/load/docs/metadata.js rename to packages/docusaurus-plugin-content-docs/src/metadata.js index 3985e67574..32e38c6560 100644 --- a/packages/docusaurus/lib/load/docs/metadata.js +++ b/packages/docusaurus-plugin-content-docs/src/metadata.js @@ -56,6 +56,7 @@ module.exports = async function processMetadata( env, order, siteConfig, + docsBasePath, ) { const filepath = path.resolve(refDir, source); const fileString = await fs.readFile(filepath, 'utf-8'); @@ -122,7 +123,7 @@ module.exports = async function processMetadata( metadata.source = path.join(refDir, source); // Build the permalink. - const {baseUrl, docsUrl} = siteConfig; + const {baseUrl} = siteConfig; // If user has own custom permalink defined in frontmatter // e.g: :baseUrl:docsUrl/:langPart/:versionPart/endiliey/:id @@ -130,7 +131,7 @@ module.exports = async function processMetadata( metadata.permalink = path.resolve( metadata.permalink .replace(/:baseUrl/, baseUrl) - .replace(/:docsUrl/, docsUrl) + .replace(/:docsUrl/, docsBasePath) .replace(/:langPart/, langPart) .replace(/:versionPart/, versionPart) .replace(/:id/, metadata.id), @@ -138,7 +139,7 @@ module.exports = async function processMetadata( } else { metadata.permalink = normalizeUrl([ baseUrl, - docsUrl, + docsBasePath, langPart, versionPart, metadata.id, diff --git a/packages/docusaurus/lib/load/docs/order.js b/packages/docusaurus-plugin-content-docs/src/order.js similarity index 100% rename from packages/docusaurus/lib/load/docs/order.js rename to packages/docusaurus-plugin-content-docs/src/order.js diff --git a/packages/docusaurus/lib/load/docs/sidebars.js b/packages/docusaurus-plugin-content-docs/src/sidebars.js similarity index 100% rename from packages/docusaurus/lib/load/docs/sidebars.js rename to packages/docusaurus-plugin-content-docs/src/sidebars.js diff --git a/packages/docusaurus-plugin-content-pages/index.js b/packages/docusaurus-plugin-content-pages/index.js index d3baec916a..7e005f1360 100644 --- a/packages/docusaurus-plugin-content-pages/index.js +++ b/packages/docusaurus-plugin-content-pages/index.js @@ -7,14 +7,12 @@ const globby = require('globby'); const path = require('path'); - -// TODO: Do not make it relative because plugins can be from node_modules. const {encodePath, fileToPath, idx} = require('@docusaurus/utils'); const DEFAULT_OPTIONS = { metadataKey: 'pagesMetadata', metadataFileName: 'pagesMetadata.json', - path: 'pages', // Path to data on filesystem. + path: 'pages', // Path to data on filesystem, relative to site dir. routeBasePath: '', // URL Route. include: ['**/*.{js,jsx}'], // Extensions to include. component: '@theme/Pages', @@ -31,6 +29,10 @@ class DocusaurusPluginContentPages { return 'docusaurus-plugin-content-pages'; } + getPathsToWatch() { + return [this.contentPath]; + } + async loadContent() { const {include} = this.options; const {env, siteConfig} = this.context; @@ -102,10 +104,6 @@ class DocusaurusPluginContentPages { }); }); } - - getPathsToWatch() { - return [this.contentPath]; - } } module.exports = DocusaurusPluginContentPages; diff --git a/packages/docusaurus/CHANGES.md b/packages/docusaurus/CHANGES.md index f73d47d0f6..5d942e6a37 100644 --- a/packages/docusaurus/CHANGES.md +++ b/packages/docusaurus/CHANGES.md @@ -1,3 +1,8 @@ # Breaking Changes +### `siteConfig.js` changes + - `siteConfig.js` renamed to `docusaurus.config.js`. +- Removed the following config options: + - `docsUrl`. Use the plugin option on `docusaurus-plugin-content-blog` instead. + - `customDocsPath`. Use the plugin option on `docusaurus-plugin-content-blog` instead. diff --git a/packages/docusaurus/lib/commands/start.js b/packages/docusaurus/lib/commands/start.js index cef70bbbc1..69f41cfb87 100644 --- a/packages/docusaurus/lib/commands/start.js +++ b/packages/docusaurus/lib/commands/start.js @@ -46,7 +46,6 @@ module.exports = async function start(siteDir, cliOptions = {}) { }); }; const {plugins} = props; - const docsRelativeDir = props.siteConfig.customDocsPath; const pluginPaths = _.compact( _.flatten( plugins.map( @@ -55,12 +54,7 @@ module.exports = async function start(siteDir, cliOptions = {}) { ), ); const fsWatcher = chokidar.watch( - [ - ...pluginPaths, - `../${docsRelativeDir}/**/*.md`, - loadConfig.configFileName, - 'sidebars.json', - ], + [...pluginPaths, loadConfig.configFileName, 'sidebars.json'], { cwd: siteDir, ignoreInitial: true, diff --git a/packages/docusaurus/lib/load/config.js b/packages/docusaurus/lib/load/config.js index 1f75fe0946..f0f41dcda8 100644 --- a/packages/docusaurus/lib/load/config.js +++ b/packages/docusaurus/lib/load/config.js @@ -25,11 +25,9 @@ const REQUIRED_FIELDS = [ const OPTIONAL_FIELDS = [ 'algolia', - 'customDocsPath', 'customFields', 'defaultLanguage', 'disableHeaderTitle', - 'docsUrl', 'githubHost', 'highlight', 'markdownPlugins', @@ -37,8 +35,7 @@ const OPTIONAL_FIELDS = [ ]; const DEFAULT_CONFIG = { - customDocsPath: 'docs', - docsUrl: 'docs', + plugins: [], }; function formatFields(fields) { diff --git a/packages/docusaurus/lib/load/docs/index.js b/packages/docusaurus/lib/load/docs/index.js deleted file mode 100644 index c19957a796..0000000000 --- a/packages/docusaurus/lib/load/docs/index.js +++ /dev/null @@ -1,144 +0,0 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -const path = require('path'); -const globby = require('globby'); -const {getSubFolder, idx} = require('@docusaurus/utils'); -const createOrder = require('./order'); -const loadSidebars = require('./sidebars'); -const processMetadata = require('./metadata'); - -async function loadDocs({ - siteDir, - docsDir, - env, - siteConfig, - skipNextRelease = false, -}) { - // @tested - load all sidebars including versioned sidebars - const docsSidebars = loadSidebars({siteDir, env}); - - // @tested - build the docs ordering such as next, previous, category and sidebar - const order = createOrder(docsSidebars); - - // Settle versions & translations from environment. - const translationEnabled = idx(env, ['translation', 'enabled']); - const enabledLanguages = - translationEnabled && idx(env, ['translation', 'enabledLanguages']); - const enabledLangTags = - (enabledLanguages && enabledLanguages.map(lang => lang.tag)) || []; - const defaultLangTag = idx(env, ['translation', 'defaultLanguage', 'tag']); - const versioningEnabled = idx(env, ['versioning', 'enabled']); - const versions = - (versioningEnabled && idx(env, ['versioning', 'versions'])) || []; - - // Prepare metadata container. - const docsMetadatas = {}; - - if (!(versioningEnabled && skipNextRelease)) { - // Metadata for default docs files. - const docsFiles = await globby(['**/*.md'], { - cwd: docsDir, - }); - await Promise.all( - docsFiles.map(async source => { - // Do not allow reserved version/ translated folder name in 'docs' - // e.g: 'docs/version-1.0.0/' should not be allowed as it can cause unwanted bug - const subFolder = getSubFolder(path.resolve(docsDir, source), docsDir); - const versionsFolders = versions.map(version => `version-${version}`); - if ([...enabledLangTags, ...versionsFolders].includes(subFolder)) { - throw new Error( - `You cannot have a folder named 'docs/${subFolder}/'`, - ); - } - - const metadata = await processMetadata( - source, - docsDir, - env, - order, - siteConfig, - ); - docsMetadatas[metadata.id] = metadata; - }), - ); - } - - // Metadata for non-default-language docs. - if (translationEnabled) { - const translatedDir = path.join(siteDir, 'translated_docs'); - const translatedFiles = await globby(['**/*.md'], { - cwd: translatedDir, - }); - await Promise.all( - translatedFiles.map(async source => { - /* - Do not process disabled & default languages folder in `translated_docs` - e.g: 'translated_docs/ja/**' should not be processed if lang 'ja' is disabled - */ - const translatedFilePath = path.resolve(translatedDir, source); - const detectedLangTag = getSubFolder(translatedFilePath, translatedDir); - if ( - detectedLangTag === defaultLangTag || - !enabledLangTags.includes(detectedLangTag) - ) { - return; - } - - const metadata = await processMetadata( - source, - translatedDir, - env, - order, - siteConfig, - ); - docsMetadatas[metadata.id] = metadata; - }), - ); - } - - // Metadata for versioned docs. - if (versioningEnabled) { - const versionedDir = path.join(siteDir, 'versioned_docs'); - const versionedFiles = await globby(['**/*.md'], { - cwd: versionedDir, - }); - await Promise.all( - versionedFiles.map(async source => { - const metadata = await processMetadata( - source, - versionedDir, - env, - order, - siteConfig, - ); - docsMetadatas[metadata.id] = metadata; - }), - ); - } - - // Get the titles of the previous and next ids so that we can use them. - Object.keys(docsMetadatas).forEach(currentID => { - const previousID = idx(docsMetadatas, [currentID, 'previous']); - if (previousID) { - const previousTitle = idx(docsMetadatas, [previousID, 'title']); - docsMetadatas[currentID].previous_title = previousTitle || 'Previous'; - } - const nextID = idx(docsMetadatas, [currentID, 'next']); - if (nextID) { - const nextTitle = idx(docsMetadatas, [nextID, 'title']); - docsMetadatas[currentID].next_title = nextTitle || 'Next'; - } - }); - - return { - docsSidebars, - docsMetadatas, - }; -} - -module.exports = loadDocs; diff --git a/packages/docusaurus/lib/load/index.js b/packages/docusaurus/lib/load/index.js index 045c0dab2f..612302e181 100644 --- a/packages/docusaurus/lib/load/index.js +++ b/packages/docusaurus/lib/load/index.js @@ -7,10 +7,11 @@ const ejs = require('ejs'); const fs = require('fs-extra'); +const _ = require('lodash'); const path = require('path'); + const {generate} = require('@docusaurus/utils'); const loadConfig = require('./config'); -const loadDocs = require('./docs'); const loadEnv = require('./env'); const loadTheme = require('./theme'); const loadRoutes = require('./routes'); @@ -40,43 +41,14 @@ module.exports = async function load(siteDir, cliOptions = {}) { `export default ${JSON.stringify(env, null, 2)};`, ); - // Docs - const docsDir = path.resolve(siteDir, '..', siteConfig.customDocsPath); - const {skipNextRelease} = cliOptions; - const {docsMetadatas, docsSidebars} = await loadDocs({ - siteDir, - docsDir, - env, - siteConfig, - skipNextRelease, - }); - await generate( - generatedFilesDir, - 'docsMetadatas.js', - `export default ${JSON.stringify(docsMetadatas, null, 2)};`, - ); - await generate( - generatedFilesDir, - 'docsSidebars.js', - `export default ${JSON.stringify(docsSidebars, null, 2)};`, - ); - - // Create source to metadata mapping. - const sourceToMetadata = {}; - Object.values(docsMetadatas).forEach( - ({source, version, permalink, language}) => { - sourceToMetadata[source] = { - version, - permalink, - language, - }; - }, - ); - // Process plugins. const pluginConfigs = siteConfig.plugins || []; - const context = {env, siteDir, generatedFilesDir, siteConfig}; - const {plugins, pluginRouteConfigs} = await loadPlugins({ + const context = {env, siteDir, generatedFilesDir, siteConfig, cliOptions}; + const { + plugins, + pluginsRouteConfigs, + pluginsLoadedContent, + } = await loadPlugins({ pluginConfigs, context, }); @@ -91,12 +63,16 @@ module.exports = async function load(siteDir, cliOptions = {}) { const versionedDir = path.join(siteDir, 'versioned_docs'); const translatedDir = path.join(siteDir, 'translated_docs'); + // TODO: Make doc dependents use the plugin's content instead + // of passing in via props. + const { + docsDir, + docs: docsMetadata, + sourceToMetadata, + } = pluginsLoadedContent[0].content; + // Generate React Router Config. - const {routesConfig, routesPaths} = await loadRoutes({ - siteConfig, - docsMetadatas, - pluginRouteConfigs, - }); + const {routesConfig, routesPaths} = await loadRoutes(pluginsRouteConfigs); await generate(generatedFilesDir, 'routes.js', routesConfig); // Generate contents metadata. @@ -105,21 +81,20 @@ module.exports = async function load(siteDir, cliOptions = {}) { '../core/templates/metadata.template.ejs', ); const metadataTemplate = fs.readFileSync(metadataTemplateFile).toString(); + const pluginMetadataImports = _.compact(pluginsLoadedContent).map( + ({metadataKey, contentPath}) => ({ + name: metadataKey, + path: contentPath, + }), + ); const metadataFile = ejs.render(metadataTemplate, { imports: [ - { - name: 'docsMetadatas', - path: '@generated/docsMetadatas', - }, + ...pluginMetadataImports, { name: 'env', path: '@generated/env', }, - { - name: 'docsSidebars', - path: '@generated/docsSidebars', - }, ], }); await generate(generatedFilesDir, 'metadata.js', metadataFile); @@ -128,8 +103,7 @@ module.exports = async function load(siteDir, cliOptions = {}) { siteConfig, siteDir, docsDir, - docsMetadatas, - docsSidebars, + docsMetadata, env, outDir, themePath, diff --git a/packages/docusaurus/lib/load/plugins.js b/packages/docusaurus/lib/load/plugins.js index fa26260361..cfb223ce38 100644 --- a/packages/docusaurus/lib/load/plugins.js +++ b/packages/docusaurus/lib/load/plugins.js @@ -6,9 +6,11 @@ */ const fs = require('fs-extra'); +const path = require('path'); +const {generate} = require('@docusaurus/utils'); module.exports = async function loadPlugins({pluginConfigs = [], context}) { - /* 1. Plugin Lifecycle - Initializiation/Constructor */ + // 1. Plugin Lifecycle - Initialization/Constructor const plugins = pluginConfigs.map(({name, path: pluginPath, options}) => { let Plugin; if (pluginPath && fs.existsSync(pluginPath)) { @@ -25,46 +27,59 @@ module.exports = async function loadPlugins({pluginConfigs = [], context}) { return new Plugin(options, context); }); - // Do not allow plugin with duplicate name - const pluginNames = new Set(); - plugins.forEach(plugin => { - const name = plugin.getName(); - if (pluginNames.has(name)) { - throw new Error(`Duplicate plugin with name '${name}' found`); - } - pluginNames.add(name); - }); - - /* 2. Plugin lifecycle - LoadContent */ - const pluginsLoadedContent = {}; - await Promise.all( + // 2. Plugin lifecycle - loadContent + // Currently plugins run lifecycle in parallel and are not order-dependent. We could change + // this in future if there are plugins which need to run in certain order or depend on + // others for data. + const pluginsLoadedContent = await Promise.all( plugins.map(async plugin => { if (!plugin.loadContent) { - return; + return null; } const name = plugin.getName(); - pluginsLoadedContent[name] = await plugin.loadContent(); + const {options} = plugin; + const {metadataKey, metadataFileName} = options; + const content = await plugin.loadContent(); + const pluginContentPath = path.join(name, metadataFileName); + const pluginContentDir = path.join(context.generatedFilesDir, name); + fs.ensureDirSync(pluginContentDir); + await generate( + pluginContentDir, + metadataFileName, + JSON.stringify(content, null, 2), + ); + const contentPath = path.join('@generated', pluginContentPath); + + return { + metadataKey, + contentPath, + content, + }; }), ); - /* 3. Plugin lifecycle - contentLoaded */ - const pluginRouteConfigs = []; + // 3. Plugin lifecycle - contentLoaded + const pluginsRouteConfigs = []; const actions = { - addRoute: config => pluginRouteConfigs.push(config), + addRoute: config => pluginsRouteConfigs.push(config), }; await Promise.all( - plugins.map(async plugin => { + plugins.map(async (plugin, index) => { if (!plugin.contentLoaded) { return; } - const name = plugin.getName(); - const content = pluginsLoadedContent[name]; - await plugin.contentLoaded({content, actions}); + const loadedContent = pluginsLoadedContent[index]; + await plugin.contentLoaded({ + content: loadedContent.content, + actions, + }); }), ); + return { plugins, - pluginRouteConfigs, + pluginsRouteConfigs, + pluginsLoadedContent, }; }; diff --git a/packages/docusaurus/lib/load/routes.js b/packages/docusaurus/lib/load/routes.js index c2ced2180a..000e06ac57 100644 --- a/packages/docusaurus/lib/load/routes.js +++ b/packages/docusaurus/lib/load/routes.js @@ -5,19 +5,13 @@ * LICENSE file in the root directory of this source tree. */ -const {normalizeUrl, generateChunkName} = require('@docusaurus/utils'); +const {generateChunkName} = require('@docusaurus/utils'); -async function loadRoutes({ - siteConfig = {}, - docsMetadatas = {}, - pluginRouteConfigs = [], -}) { +async function loadRoutes(pluginsRouteConfigs) { const imports = [ `import React from 'react';`, `import Loadable from 'react-loadable';`, `import Loading from '@theme/Loading';`, - `import Doc from '@theme/Doc';`, - `import DocBody from '@theme/DocBody';`, `import NotFound from '@theme/NotFound';`, ]; @@ -28,50 +22,29 @@ async function loadRoutes({ } }; - // Docs. - const {docsUrl, baseUrl} = siteConfig; - function genDocsRoute(metadata) { - const {permalink, source} = metadata; - addRoutesPath(permalink); - return ` -{ - path: '${permalink}', - exact: true, - component: Loadable({ - loader: () => import(/* webpackChunkName: '${generateChunkName( - permalink, - )}' */ '${source}'), - loading: Loading, - render(loaded, props) { - let Content = loaded.default; - return ( - - - - ); - } - }) -}`; - } - - const rootDocsUrl = normalizeUrl([baseUrl, docsUrl]); - const docsRoutes = ` -{ - path: '${rootDocsUrl}', - component: Doc, - routes: [${Object.values(docsMetadatas) - .map(genDocsRoute) - .join(',')}], -}`; - const notFoundRoute = ` { path: '*', component: NotFound, }`; - const routes = pluginRouteConfigs.map(pluginRouteConfig => { - const {path, component, metadata, modules} = pluginRouteConfig; + function generateRouteCode(pluginRouteConfig) { + const {path, component, metadata, modules, routes} = pluginRouteConfig; + if (routes) { + return ` +{ + path: '${path}', + component: Loadable({ + loader: () => import(/* webpackChunkName: '${generateChunkName( + component, + 'component', + )}' */'${component}'), + loading: Loading, + }), + routes: [${routes.map(generateRouteCode).join(',')}], +}`; + } + addRoutesPath(path); return ` { @@ -109,14 +82,14 @@ ${modules } }) }`; - }); + } + + const routes = pluginsRouteConfigs.map(generateRouteCode); const routesConfig = ` ${imports.join('\n')} const routes = [ -// Docs.${docsRoutes}, - // Plugins.${routes.join(',')}, // Not Found.${notFoundRoute}, diff --git a/packages/docusaurus/lib/theme/BlogPost/index.js b/packages/docusaurus/lib/theme/BlogPost/index.js index 109afd4711..dfba154dfa 100644 --- a/packages/docusaurus/lib/theme/BlogPost/index.js +++ b/packages/docusaurus/lib/theme/BlogPost/index.js @@ -6,9 +6,9 @@ */ import React, {useContext} from 'react'; + import Head from '@docusaurus/Head'; import Layout from '@theme/Layout'; // eslint-disable-line - import DocusaurusContext from '@docusaurus/context'; import Post from '../Post'; import styles from './styles.module.css'; diff --git a/packages/docusaurus/lib/theme/DocBody/index.js b/packages/docusaurus/lib/theme/DocBody/index.js index d91ef8bafb..c17acbc08e 100644 --- a/packages/docusaurus/lib/theme/DocBody/index.js +++ b/packages/docusaurus/lib/theme/DocBody/index.js @@ -13,17 +13,19 @@ import DocusaurusContext from '@docusaurus/context'; import styles from './styles.module.css'; function DocBody(props) { - const {children, metadata} = props; + const {metadata, modules} = props; const context = useContext(DocusaurusContext); useEffect(() => { context.setContext({metadata}); }, []); + const DocContents = modules[0]; + return (

{metadata.title}

- {children} +
diff --git a/packages/docusaurus/lib/theme/DocsPaginator/index.js b/packages/docusaurus/lib/theme/DocsPaginator/index.js index 203aa35d77..1c9d2218e6 100644 --- a/packages/docusaurus/lib/theme/DocsPaginator/index.js +++ b/packages/docusaurus/lib/theme/DocsPaginator/index.js @@ -14,18 +14,19 @@ import styles from './styles.module.css'; function DocsPaginator() { const context = useContext(DocusaurusContext); - const {docsMetadatas, metadata} = context; - if (!metadata) { + const {docsMetadata, metadata} = context; + if (!metadata || !docsMetadata) { return null; } + const {docs} = docsMetadata; return (
- {metadata.previous && docsMetadatas[metadata.previous] && ( + {metadata.previous && docs[metadata.previous] && ( + to={docs[metadata.previous].permalink}> @@ -37,10 +38,10 @@ function DocsPaginator() { )}
- {metadata.next && docsMetadatas[metadata.next] && ( + {metadata.next && docs[metadata.next] && ( + to={docs[metadata.next].permalink}> {metadata.next_title}{' '} diff --git a/packages/docusaurus/lib/theme/Navbar/index.js b/packages/docusaurus/lib/theme/Navbar/index.js index 1447749dd2..7943bdc422 100644 --- a/packages/docusaurus/lib/theme/Navbar/index.js +++ b/packages/docusaurus/lib/theme/Navbar/index.js @@ -14,12 +14,7 @@ import styles from './styles.module.css'; function Navbar(props) { const context = useContext(DocusaurusContext); - const { - siteConfig = {}, - env = {}, - metadata = {}, - docsMetadatas = {}, - } = context; + const {siteConfig = {}, env = {}, metadata = {}, docsMetadata} = context; const { baseUrl, headerLinks, @@ -28,6 +23,7 @@ function Navbar(props) { title, disableHeaderTitle, } = siteConfig; + const {language: thisLanguage, version: thisVersion} = metadata; const translationEnabled = env.translation.enabled; @@ -56,8 +52,9 @@ function Navbar(props) { ? `version-${thisVersion || env.versioning.defaultVersion}-` : ''; const id = langPart + versionPart + link.doc; - if (!docsMetadatas[id]) { - const errorStr = `We could not find the doc wih id: ${id}. Please check your headerLinks correctly\n`; + const {docs} = docsMetadata; + if (!docs[id]) { + const errorStr = `We could not find the doc with id: ${id}. Please check your headerLinks correctly\n`; throw new Error(errorStr); } return ( @@ -65,7 +62,7 @@ function Navbar(props) { + to={docs[id].permalink}> {link.label} diff --git a/packages/docusaurus/lib/theme/Sidebar/index.js b/packages/docusaurus/lib/theme/Sidebar/index.js index 7d9746e9e1..b69702a658 100644 --- a/packages/docusaurus/lib/theme/Sidebar/index.js +++ b/packages/docusaurus/lib/theme/Sidebar/index.js @@ -15,14 +15,14 @@ import styles from './styles.module.css'; function Sidebar() { const context = useContext(DocusaurusContext); - const {metadata = {}, docsSidebars, docsMetadatas} = context; + const {metadata = {}, docsMetadata} = context; const {sidebar, language} = metadata; if (!sidebar) { return null; } - const thisSidebar = docsSidebars[sidebar]; + const thisSidebar = docsMetadata.docsSidebars[sidebar]; if (!thisSidebar) { throw new Error(`Can not find ${sidebar} config`); @@ -30,7 +30,7 @@ function Sidebar() { const convertDocLink = item => { const linkID = (language ? `${language}-` : '') + item.id; - const linkMetadata = docsMetadatas[linkID]; + const linkMetadata = docsMetadata.docs[linkID]; if (!linkMetadata) { throw new Error( diff --git a/packages/docusaurus/test/__fixtures__/custom-site/docusaurus.config.js b/packages/docusaurus/test/__fixtures__/custom-site/docusaurus.config.js index 50845a6f81..fa41d870c0 100644 --- a/packages/docusaurus/test/__fixtures__/custom-site/docusaurus.config.js +++ b/packages/docusaurus/test/__fixtures__/custom-site/docusaurus.config.js @@ -19,6 +19,12 @@ module.exports = { headerIcon: 'img/docusaurus.svg', favicon: 'img/docusaurus.ico', plugins: [ + { + name: '@docusaurus/plugin-content-docs', + options: { + path: '../docs', + }, + }, { name: '@docusaurus/plugin-content-pages', }, diff --git a/packages/docusaurus/test/__fixtures__/simple-site/docusaurus.config.js b/packages/docusaurus/test/__fixtures__/simple-site/docusaurus.config.js index 9f9d58fe51..fd4fa9a99f 100644 --- a/packages/docusaurus/test/__fixtures__/simple-site/docusaurus.config.js +++ b/packages/docusaurus/test/__fixtures__/simple-site/docusaurus.config.js @@ -19,6 +19,12 @@ module.exports = { headerIcon: 'img/docusaurus.svg', favicon: 'img/docusaurus.ico', plugins: [ + { + name: '@docusaurus/plugin-content-docs', + options: { + path: '../docs', + }, + }, { name: '@docusaurus/plugin-content-pages', }, diff --git a/packages/docusaurus/test/__fixtures__/translated-site/docusaurus.config.js b/packages/docusaurus/test/__fixtures__/translated-site/docusaurus.config.js index c1f6d78b4a..9dd0c06bd4 100644 --- a/packages/docusaurus/test/__fixtures__/translated-site/docusaurus.config.js +++ b/packages/docusaurus/test/__fixtures__/translated-site/docusaurus.config.js @@ -20,6 +20,12 @@ module.exports = { headerIcon: 'img/docusaurus.svg', favicon: 'img/docusaurus.ico', plugins: [ + { + name: '@docusaurus/plugin-content-docs', + options: { + path: '../docs', + }, + }, { name: '@docusaurus/plugin-content-pages', }, diff --git a/packages/docusaurus/test/__fixtures__/transversioned-site/docusaurus.config.js b/packages/docusaurus/test/__fixtures__/transversioned-site/docusaurus.config.js index c1f6d78b4a..9dd0c06bd4 100644 --- a/packages/docusaurus/test/__fixtures__/transversioned-site/docusaurus.config.js +++ b/packages/docusaurus/test/__fixtures__/transversioned-site/docusaurus.config.js @@ -20,6 +20,12 @@ module.exports = { headerIcon: 'img/docusaurus.svg', favicon: 'img/docusaurus.ico', plugins: [ + { + name: '@docusaurus/plugin-content-docs', + options: { + path: '../docs', + }, + }, { name: '@docusaurus/plugin-content-pages', }, diff --git a/packages/docusaurus/test/__fixtures__/versioned-site/docusaurus.config.js b/packages/docusaurus/test/__fixtures__/versioned-site/docusaurus.config.js index 9f9d58fe51..fd4fa9a99f 100644 --- a/packages/docusaurus/test/__fixtures__/versioned-site/docusaurus.config.js +++ b/packages/docusaurus/test/__fixtures__/versioned-site/docusaurus.config.js @@ -19,6 +19,12 @@ module.exports = { headerIcon: 'img/docusaurus.svg', favicon: 'img/docusaurus.ico', plugins: [ + { + name: '@docusaurus/plugin-content-docs', + options: { + path: '../docs', + }, + }, { name: '@docusaurus/plugin-content-pages', }, diff --git a/packages/docusaurus/test/load/config.test.js b/packages/docusaurus/test/load/config.test.js index 5e8c164fb0..852e8ecc60 100644 --- a/packages/docusaurus/test/load/config.test.js +++ b/packages/docusaurus/test/load/config.test.js @@ -16,8 +16,6 @@ describe('loadConfig', () => { expect(config).toMatchInlineSnapshot(` Object { "baseUrl": "/", - "customDocsPath": "docs", - "docsUrl": "docs", "favicon": "img/docusaurus.ico", "headerIcon": "img/docusaurus.svg", "headerLinks": Array [ @@ -35,6 +33,12 @@ Object { ], "organizationName": "endiliey", "plugins": Array [ + Object { + "name": "@docusaurus/plugin-content-docs", + "options": Object { + "path": "../docs", + }, + }, Object { "name": "@docusaurus/plugin-content-pages", }, diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 73f157573b..6ac228a754 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -11,7 +11,6 @@ module.exports = { organizationName: 'facebook', projectName: 'docusaurus', baseUrl: '/', - customDocsPath: './docs', url: 'https://docusaurus.io', headerLinks: [ {doc: 'installation', label: 'Docs'}, @@ -30,6 +29,12 @@ module.exports = { algoliaOptions: {}, }, plugins: [ + { + name: '@docusaurus/plugin-content-docs', + options: { + path: '../docs', + }, + }, { name: '@docusaurus/plugin-content-blog', options: {