feat(core): allow sourcing from multiple static directories (#4095)

* [WIP] Implementaion of multiple directory static sourcing

* Move default to validation

* Update test

* Refactor

* Port to MDX loader

* Fix

* Move dogfooding assets

* Doc writeup

* Restore assets

* Support absolute paths

* Dogfood absolute path

* Fix

* More tests

* Fix snapshots

Co-authored-by: Joshua Chen <sidachen2003@gmail.com>
This commit is contained in:
Oliver Ullman 2021-11-18 11:26:26 -03:00 committed by GitHub
parent 3f18c928bb
commit 1366c31201
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
43 changed files with 238 additions and 181 deletions

View file

@ -361,6 +361,20 @@ Attempting to add unknown field in the config will lead to error in build time:
Error: The field(s) 'foo', 'bar' are not recognized in docusaurus.config.js
```
### `staticDirectories` {#staticdirectories}
An array of paths, relative to the site's directory or absolute. Files under these paths will be copied to the build output as-is.
- Type: `string[]`
Example:
```js title="docusaurus.config.js"
module.exports = {
staticDirectories: ['static'],
};
```
### `scripts` {#scripts}
An array of scripts to load. The values can be either strings or plain objects of attribute-value maps. The `<script>` tags will be inserted in the HTML `<head>`.

View file

@ -5,9 +5,7 @@ description: Handling assets in Docusaurus Markdown
slug: /markdown-features/assets
---
Sometimes you want to link to static assets directly from Markdown files, and it is convenient to co-locate the asset next to the Markdown file using it.
We have setup Webpack loaders to handle most common file types, so that when you import a file, you get its url, and the asset is automatically copied to the output folder.
Sometimes you want to link to assets (e.g. docx files, images...) directly from Markdown files, and it is convenient to co-locate the asset next to the Markdown file using it.
Let's imagine the following file structure:
@ -145,3 +143,16 @@ import ThemedImage from '@theme/ThemedImage';
}}
/>
```
## Static assets {#static-assets}
If a Markdown link or image has an absolute path, the path will be seen as a file path and will be resolved from the static directories. For example, if you have configured [static directories](../../static-assets.md) to be `['public', 'static']`, then for the following image:
```md title="my-doc.md"
![An image from the static](/img/docusaurus.png)
```
Docusaurus will try to look for it in both `static/img/docusaurus.png` and `public/img/docusaurus.png`. The link will then be converted to a `require` call instead of staying as a URL. This is desirable in two regards:
1. You don't have to worry about base URL, which Docusaurus will take care of when serving the asset;
2. The image enters Webpack's build pipeline and its name will be appended by a hash, which enables browsers to aggressively cache the image and improves your site's performance.

View file

@ -3,7 +3,7 @@ id: static-assets
title: Static Assets
---
Every website needs assets: images, stylesheets, favicons etc. In such cases, you can create a directory named `static` at the root of your project.
Every website needs assets: images, stylesheets, favicons etc. By default, you are suggested to put these assets in the `static` folder.
Every file you put into **that directory will be copied** into the root of the generated `build` folder with the directory hierarchy preserved. E.g. if you add a file named `sun.jpg` to the static folder, it will be copied to `build/sun.jpg`.
@ -12,13 +12,31 @@ This means that:
- for site `baseUrl: '/'`, the image `/static/img/docusaurus.png` will be served at `/img/docusaurus.png`.
- for site `baseUrl: '/subpath/'`, the image `/static/img/docusaurus.png` will be served at `/subpath/img/docusaurus.png`.
You can customize the static directory sources in `docusaurus.config.js`. For example, we can add `public` as another possible path:
```js title="docusaurus.config.js"
module.exports = {
title: 'My site',
staticDirectories: ['public', 'static'],
// ...
};
```
Now, all files in `public` as well as `static` will be copied to the build output.
## Referencing your static asset {#referencing-your-static-asset}
You can reference assets from the `static` folder in your code using absolute paths, but this is not ideal because changing the site `baseUrl` will **break those link**s.
In JSX, you can reference assets from the `static` folder in your code using absolute paths, but this is not ideal because changing the site `baseUrl` will **break those links**. For the image `<img src="/img/docusaurus.png" />` served at `https://example.com/test`, the browser will try to resolve it from the URL root, i.e. as `https://example.com/img/docusaurus.png`, which will fail because it's actually served at `https://example.com/test/img/docusaurus.png`.
You can `import` / `require()` the static asset (recommended), or use the `useBaseUrl` utility function: both prepend the `baseUrl` to paths for you.
### JSX example {#jsx-example}
:::info
In Markdown, things are different: you can stick to use absolute paths because Docusaurus actually handles them as `require` calls instead of URLs when parsing the Markdown. See [Markdown static assets](./guides/markdown-features/markdown-features-assets.mdx).
:::
### Examples {#examples}
```jsx title="MyComponent.js"
import DocusaurusImageUrl from '@site/static/img/docusaurus.png';
@ -44,30 +62,6 @@ import DocusaurusLogoWithKeytar from '@site/static/img/docusaurus_keytar.svg';
<DocusaurusLogoWithKeytar title="Docusaurus Logo" className="logo" />;
```
### Markdown example {#markdown-example}
Markdown links and images referencing assets of the static folder will be converted to `require("@site/static/assetName.png")"`, and **the site baseUrl will be automatically prepended** for you.
```md title="my-doc.md"
![Docusaurus](/img/docusaurus.png)
```
Thanks to MDX, you can also use `useBaseUrl` utility function in Markdown files! You'd have to use html tags like `<img>` instead of the Markdown image syntax though. The syntax is exactly the same as in JSX.
```jsx title="my-doc.mdx"
---
id: my-doc
title: My Doc
---
// Add to the top of the file below the front matter.
import useBaseUrl from '@docusaurus/useBaseUrl';
...
<img alt="Docusaurus with Keytar" src={useBaseUrl('/img/docusaurus_keytar.svg')} />
```
### Caveats {#caveats}
Keep in mind that: