feat(v2): polyfill automatically depending on browserslist (#1857)

* feat(v2): polyfill corejs and ie11 compat

* use corejs/stable

* useBuiltIns => usage instead of entry

* chngelo

* nits

* breaking: withBaseUrl -> useBaseUrl

* nits

* loose mode for faster perf and smaller bundle
This commit is contained in:
Endi 2019-10-21 11:09:16 +07:00 committed by GitHub
parent ee936f62b5
commit abdc647b07
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 181 additions and 163 deletions

View file

@ -8,6 +8,9 @@
- Fix `swizzle` command not being able to swizzle single js file. - Fix `swizzle` command not being able to swizzle single js file.
- Fix logo URL in footer to be appended with baseUrl automatically. - Fix logo URL in footer to be appended with baseUrl automatically.
- Add the option `--no-open` for `start` command. - Add the option `--no-open` for `start` command.
- Set `@babel/env` useBuiltins to `usage`. This will automatically use browserlist and import polyfills required.
- Modified TerserWebpackPlugin `terserOptions` for better cross-browser compatibility.
- **BREAKING** `withBaseUrl` is renamed to `useBaseUrl` because its a React Hooks. Make sure you import/rename it correctly. Eg: `import useBaseUrl from '@docusaurus/useBaseUrl`;
- Fix potential security vulnerability because we're exposing the directory structure of the host machine. - Fix potential security vulnerability because we're exposing the directory structure of the host machine.
## 2.0.0-alpha.27 ## 2.0.0-alpha.27

View file

@ -10,7 +10,7 @@ import classnames from 'classnames';
import Layout from '@theme/Layout'; import Layout from '@theme/Layout';
import Link from '@docusaurus/Link'; import Link from '@docusaurus/Link';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import withBaseUrl from '@docusaurus/withBaseUrl'; import useBaseUrl from '@docusaurus/useBaseUrl';
import styles from './styles.module.css'; import styles from './styles.module.css';
const features = [ const features = [
@ -46,6 +46,21 @@ const features = [
}, },
]; ];
function Feature({imageUrl, title, description}) {
const imgUrl = useBaseUrl(imageUrl);
return (
<div className={classnames('col col--4', styles.feature)}>
{imgUrl && (
<div className="text--center">
<img className={styles.featureImage} src={imgUrl} alt={title} />
</div>
)}
<h3>{title}</h3>
<p>{description}</p>
</div>
);
}
function Home() { function Home() {
const context = useDocusaurusContext(); const context = useDocusaurusContext();
const {siteConfig = {}} = context; const {siteConfig = {}} = context;
@ -63,7 +78,7 @@ function Home() {
'button button--outline button--secondary button--lg', 'button button--outline button--secondary button--lg',
styles.getStarted, styles.getStarted,
)} )}
to={withBaseUrl('docs/doc1')}> to={useBaseUrl('docs/doc1')}>
Get Started Get Started
</Link> </Link>
</div> </div>
@ -74,22 +89,8 @@ function Home() {
<section className={styles.features}> <section className={styles.features}>
<div className="container"> <div className="container">
<div className="row"> <div className="row">
{features.map(({imageUrl, title, description}, idx) => ( {features.map((props, idx) => (
<div <Feature key={idx} {...props} />
key={idx}
className={classnames('col col--4', styles.feature)}>
{imageUrl && (
<div className="text--center">
<img
className={styles.featureImage}
src={withBaseUrl(imageUrl)}
alt={title}
/>
</div>
)}
<h3>{title}</h3>
<p>{description}</p>
</div>
))} ))}
</div> </div>
</div> </div>

View file

@ -9,7 +9,7 @@ import React from 'react';
import Head from '@docusaurus/Head'; import Head from '@docusaurus/Head';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import withBaseUrl from '@docusaurus/withBaseUrl'; import useBaseUrl from '@docusaurus/useBaseUrl';
import DocPaginator from '@theme/DocPaginator'; import DocPaginator from '@theme/DocPaginator';
import styles from './styles.module.css'; import styles from './styles.module.css';
@ -45,6 +45,8 @@ function DocItem(props) {
keywords, keywords,
} = metadata; } = metadata;
const metaImageUrl = siteUrl + useBaseUrl(metaImage);
return ( return (
<div> <div>
<Head> <Head>
@ -56,18 +58,8 @@ function DocItem(props) {
{keywords && keywords.length && ( {keywords && keywords.length && (
<meta name="keywords" content={keywords.join(',')} /> <meta name="keywords" content={keywords.join(',')} />
)} )}
{metaImage && ( {metaImage && <meta property="og:image" content={metaImageUrl} />}
<meta {metaImage && <meta property="twitter:image" content={metaImageUrl} />}
property="og:image"
content={siteUrl + withBaseUrl(metaImage)}
/>
)}
{metaImage && (
<meta
property="twitter:image"
content={siteUrl + withBaseUrl(metaImage)}
/>
)}
{metaImage && ( {metaImage && (
<meta name="twitter:image:alt" content={`Image for ${title}`} /> <meta name="twitter:image:alt" content={`Image for ${title}`} />
)} )}

View file

@ -10,7 +10,27 @@ import classnames from 'classnames';
import Link from '@docusaurus/Link'; import Link from '@docusaurus/Link';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import withBaseUrl from '@docusaurus/withBaseUrl'; import useBaseUrl from '@docusaurus/useBaseUrl';
function FooterLink({item}) {
const toUrl = useBaseUrl(item.to);
return (
<Link
className="footer__link-item"
{...item}
{...(item.href
? {
target: '_blank',
rel: 'noopener noreferrer',
href: item.href,
}
: {
to: toUrl,
})}>
{item.label}
</Link>
);
}
function Footer() { function Footer() {
const context = useDocusaurusContext(); const context = useDocusaurusContext();
@ -18,12 +38,13 @@ function Footer() {
const {themeConfig = {}} = siteConfig; const {themeConfig = {}} = siteConfig;
const {footer} = themeConfig; const {footer} = themeConfig;
const {copyright, links = [], logo = {}} = footer || {};
const logoUrl = useBaseUrl(logo.src);
if (!footer) { if (!footer) {
return null; return null;
} }
const {copyright, links = [], logo} = footer;
return ( return (
<footer <footer
className={classnames('footer', { className={classnames('footer', {
@ -43,20 +64,7 @@ function Footer() {
<ul className="footer__items"> <ul className="footer__items">
{linkItem.items.map(item => ( {linkItem.items.map(item => (
<li key={item.href || item.to} className="footer__item"> <li key={item.href || item.to} className="footer__item">
<Link <FooterLink item={item} />
className="footer__link-item"
{...item}
{...(item.href
? {
target: '_blank',
rel: 'noopener noreferrer',
href: item.href,
}
: {
to: withBaseUrl(item.to),
})}>
{item.label}
</Link>
</li> </li>
))} ))}
</ul> </ul>
@ -69,11 +77,7 @@ function Footer() {
<div className="text--center"> <div className="text--center">
{logo && logo.src && ( {logo && logo.src && (
<div className="margin-bottom--sm"> <div className="margin-bottom--sm">
<img <img className="footer__logo" alt={logo.alt} src={logoUrl} />
className="footer__logo"
alt={logo.alt}
src={withBaseUrl(logo.src)}
/>
</div> </div>
)} )}
{copyright} {copyright}

View file

@ -8,7 +8,7 @@
import React from 'react'; import React from 'react';
import Head from '@docusaurus/Head'; import Head from '@docusaurus/Head';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import withBaseUrl from '@docusaurus/withBaseUrl'; import useBaseUrl from '@docusaurus/useBaseUrl';
import Navbar from '@theme/Navbar'; import Navbar from '@theme/Navbar';
import Footer from '@theme/Footer'; import Footer from '@theme/Footer';
@ -34,6 +34,8 @@ function Layout(props) {
} = props; } = props;
const metaTitle = title || `${defaultTitle} · ${tagline}`; const metaTitle = title || `${defaultTitle} · ${tagline}`;
const metaImage = image || defaultImage; const metaImage = image || defaultImage;
const metaImageUrl = siteUrl + useBaseUrl(metaImage);
const faviconUrl = useBaseUrl(favicon);
return ( return (
<React.Fragment> <React.Fragment>
<Head> <Head>
@ -42,7 +44,7 @@ function Layout(props) {
<meta name="viewport" content="width=device-width" /> <meta name="viewport" content="width=device-width" />
{metaTitle && <title>{metaTitle}</title>} {metaTitle && <title>{metaTitle}</title>}
{metaTitle && <meta property="og:title" content={metaTitle} />} {metaTitle && <meta property="og:title" content={metaTitle} />}
{favicon && <link rel="shortcut icon" href={withBaseUrl(favicon)} />} {favicon && <link rel="shortcut icon" href={faviconUrl} />}
{description && <meta name="description" content={description} />} {description && <meta name="description" content={description} />}
{description && ( {description && (
<meta property="og:description" content={description} /> <meta property="og:description" content={description} />
@ -50,18 +52,8 @@ function Layout(props) {
{keywords && keywords.length && ( {keywords && keywords.length && (
<meta name="keywords" content={keywords.join(',')} /> <meta name="keywords" content={keywords.join(',')} />
)} )}
{metaImage && ( {metaImage && <meta property="og:image" content={metaImageUrl} />}
<meta {metaImage && <meta property="twitter:image" content={metaImageUrl} />}
property="og:image"
content={siteUrl + withBaseUrl(metaImage)}
/>
)}
{metaImage && (
<meta
property="twitter:image"
content={siteUrl + withBaseUrl(metaImage)}
/>
)}
{metaImage && ( {metaImage && (
<meta name="twitter:image:alt" content={`Image for ${metaTitle}`} /> <meta name="twitter:image:alt" content={`Image for ${metaTitle}`} />
)} )}

View file

@ -11,7 +11,7 @@ import Toggle from 'react-toggle';
import Link from '@docusaurus/Link'; import Link from '@docusaurus/Link';
import Head from '@docusaurus/Head'; import Head from '@docusaurus/Head';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import withBaseUrl from '@docusaurus/withBaseUrl'; import useBaseUrl from '@docusaurus/useBaseUrl';
import SearchBar from '@theme/SearchBar'; import SearchBar from '@theme/SearchBar';
@ -20,6 +20,7 @@ import classnames from 'classnames';
import styles from './styles.module.css'; import styles from './styles.module.css';
function NavLink(props) { function NavLink(props) {
const toUrl = useBaseUrl(props.to);
return ( return (
<Link <Link
className="navbar__item navbar__link" className="navbar__item navbar__link"
@ -32,7 +33,7 @@ function NavLink(props) {
} }
: { : {
activeClassName: 'navbar__link--active', activeClassName: 'navbar__link--active',
to: withBaseUrl(props.to), to: toUrl,
})}> })}>
{props.label} {props.label}
</Link> </Link>
@ -54,7 +55,7 @@ function Navbar() {
const {siteConfig = {}} = context; const {siteConfig = {}} = context;
const {baseUrl, themeConfig = {}} = siteConfig; const {baseUrl, themeConfig = {}} = siteConfig;
const {algolia, navbar = {}} = themeConfig; const {algolia, navbar = {}} = themeConfig;
const {title, logo, links = []} = navbar; const {title, logo = {}, links = []} = navbar;
const showSidebar = useCallback(() => { const showSidebar = useCallback(() => {
setSidebarShown(true); setSidebarShown(true);
@ -82,6 +83,7 @@ function Navbar() {
} }
}; };
const logoUrl = useBaseUrl(logo.src);
return ( return (
<React.Fragment> <React.Fragment>
<Head> <Head>
@ -120,11 +122,7 @@ function Navbar() {
</div> </div>
<Link className="navbar__brand" to={baseUrl}> <Link className="navbar__brand" to={baseUrl}>
{logo != null && ( {logo != null && (
<img <img className="navbar__logo" src={logoUrl} alt={logo.alt} />
className="navbar__logo"
src={withBaseUrl(logo.src)}
alt={logo.alt}
/>
)} )}
{title != null && ( {title != null && (
<strong <strong
@ -176,11 +174,7 @@ function Navbar() {
<div className="navbar__sidebar__brand"> <div className="navbar__sidebar__brand">
<Link className="navbar__brand" onClick={hideSidebar} to={baseUrl}> <Link className="navbar__brand" onClick={hideSidebar} to={baseUrl}>
{logo != null && ( {logo != null && (
<img <img className="navbar__logo" src={logoUrl} alt={logo.alt} />
className="navbar__logo"
src={withBaseUrl(logo.src)}
alt={logo.alt}
/>
)} )}
{title != null && <strong>{title}</strong>} {title != null && <strong>{title}</strong>}
</Link> </Link>

View file

@ -0,0 +1,52 @@
/**
* 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.
*/
import useBaseUrl from '../useBaseUrl';
import useDocusaurusContext from '../useDocusaurusContext';
jest.mock('../useDocusaurusContext', () => jest.fn(), {virtual: true});
const mockedContext = <jest.Mock>useDocusaurusContext;
describe('useBaseUrl', () => {
test('empty base URL', () => {
mockedContext.mockImplementation(() => ({
siteConfig: {
baseUrl: '/',
},
}));
expect(useBaseUrl('hello')).toEqual('/hello');
expect(useBaseUrl('/hello')).toEqual('/hello');
expect(useBaseUrl('hello/')).toEqual('/hello/');
expect(useBaseUrl('/hello/')).toEqual('/hello/');
expect(useBaseUrl('hello/byebye')).toEqual('/hello/byebye');
expect(useBaseUrl('/hello/byebye')).toEqual('/hello/byebye');
expect(useBaseUrl('hello/byebye/')).toEqual('/hello/byebye/');
expect(useBaseUrl('/hello/byebye/')).toEqual('/hello/byebye/');
expect(useBaseUrl('https://github.com')).toEqual('https://github.com');
expect(useBaseUrl('//reactjs.org')).toEqual('//reactjs.org');
});
test('non-empty base URL', () => {
mockedContext.mockImplementation(() => ({
siteConfig: {
baseUrl: '/docusaurus/',
},
}));
expect(useBaseUrl('hello')).toEqual('/docusaurus/hello');
expect(useBaseUrl('/hello')).toEqual('/docusaurus/hello');
expect(useBaseUrl('hello/')).toEqual('/docusaurus/hello/');
expect(useBaseUrl('/hello/')).toEqual('/docusaurus/hello/');
expect(useBaseUrl('hello/byebye')).toEqual('/docusaurus/hello/byebye');
expect(useBaseUrl('/hello/byebye')).toEqual('/docusaurus/hello/byebye');
expect(useBaseUrl('hello/byebye/')).toEqual('/docusaurus/hello/byebye/');
expect(useBaseUrl('/hello/byebye/')).toEqual('/docusaurus/hello/byebye/');
expect(useBaseUrl('https://github.com')).toEqual('https://github.com');
expect(useBaseUrl('//reactjs.org')).toEqual('//reactjs.org');
});
});

View file

@ -1,52 +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.
*/
import withBaseUrl from '../withBaseUrl';
import useDocusaurusContext from '../useDocusaurusContext';
jest.mock('../useDocusaurusContext', () => jest.fn(), {virtual: true});
const mockedContext = <jest.Mock>useDocusaurusContext;
describe('withBaseUrl', () => {
test('empty base URL', () => {
mockedContext.mockImplementation(() => ({
siteConfig: {
baseUrl: '/',
},
}));
expect(withBaseUrl('hello')).toEqual('/hello');
expect(withBaseUrl('/hello')).toEqual('/hello');
expect(withBaseUrl('hello/')).toEqual('/hello/');
expect(withBaseUrl('/hello/')).toEqual('/hello/');
expect(withBaseUrl('hello/byebye')).toEqual('/hello/byebye');
expect(withBaseUrl('/hello/byebye')).toEqual('/hello/byebye');
expect(withBaseUrl('hello/byebye/')).toEqual('/hello/byebye/');
expect(withBaseUrl('/hello/byebye/')).toEqual('/hello/byebye/');
expect(withBaseUrl('https://github.com')).toEqual('https://github.com');
expect(withBaseUrl('//reactjs.org')).toEqual('//reactjs.org');
});
test('non-empty base URL', () => {
mockedContext.mockImplementation(() => ({
siteConfig: {
baseUrl: '/docusaurus/',
},
}));
expect(withBaseUrl('hello')).toEqual('/docusaurus/hello');
expect(withBaseUrl('/hello')).toEqual('/docusaurus/hello');
expect(withBaseUrl('hello/')).toEqual('/docusaurus/hello/');
expect(withBaseUrl('/hello/')).toEqual('/docusaurus/hello/');
expect(withBaseUrl('hello/byebye')).toEqual('/docusaurus/hello/byebye');
expect(withBaseUrl('/hello/byebye')).toEqual('/docusaurus/hello/byebye');
expect(withBaseUrl('hello/byebye/')).toEqual('/docusaurus/hello/byebye/');
expect(withBaseUrl('/hello/byebye/')).toEqual('/docusaurus/hello/byebye/');
expect(withBaseUrl('https://github.com')).toEqual('https://github.com');
expect(withBaseUrl('//reactjs.org')).toEqual('//reactjs.org');
});
});

View file

@ -5,7 +5,6 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import * as React from 'react'; import React from 'react';
import {DocusaurusContext} from '@docusaurus/types';
export default React.createContext<DocusaurusContext>({}); export default React.createContext({});

View file

@ -7,10 +7,14 @@
import useDocusaurusContext from './useDocusaurusContext'; import useDocusaurusContext from './useDocusaurusContext';
function withBaseUrl(url: string): string { export default function useBaseUrl(url) {
const {siteConfig} = useDocusaurusContext(); const {siteConfig} = useDocusaurusContext();
const {baseUrl = '/'} = siteConfig || {}; const {baseUrl = '/'} = siteConfig || {};
if (!url) {
return url;
}
const externalRegex = /^(https?:|\/\/)/; const externalRegex = /^(https?:|\/\/)/;
if (externalRegex.test(url)) { if (externalRegex.test(url)) {
return url; return url;
@ -20,5 +24,3 @@ function withBaseUrl(url: string): string {
} }
return baseUrl + url; return baseUrl + url;
} }
export default withBaseUrl;

View file

@ -7,9 +7,8 @@
import {useContext} from 'react'; import {useContext} from 'react';
import context from './context'; import context from './context';
import {DocusaurusContext} from '@docusaurus/types';
function useDocusaurusContext(): DocusaurusContext { function useDocusaurusContext() {
return useContext(context); return useContext(context);
} }

View file

@ -8,18 +8,19 @@
import React from 'react'; import React from 'react';
import Head from '@docusaurus/Head'; import Head from '@docusaurus/Head';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import withBaseUrl from '@docusaurus/withBaseUrl'; import useBaseUrl from '@docusaurus/useBaseUrl';
function Layout(props) { function Layout(props) {
const context = useDocusaurusContext(); const context = useDocusaurusContext();
const {siteConfig = {}} = context; const {siteConfig = {}} = context;
const {favicon, tagline, title: defaultTitle} = siteConfig; const {favicon, tagline, title: defaultTitle} = siteConfig;
const {children, title, description} = props; const {children, title, description} = props;
const faviconUrl = useBaseUrl(favicon);
return ( return (
<React.Fragment> <React.Fragment>
<Head defaultTitle={`${defaultTitle} · ${tagline}`}> <Head defaultTitle={`${defaultTitle} · ${tagline}`}>
{title && <title>{`${title} · ${tagline}`}</title>} {title && <title>{`${title} · ${tagline}`}</title>}
{favicon && <link rel="shortcut icon" href={withBaseUrl(favicon)} />} {favicon && <link rel="shortcut icon" href={faviconUrl} />}
{description && <meta name="description" content={description} />} {description && <meta name="description" content={description} />}
{description && ( {description && (
<meta property="og:description" content={description} /> <meta property="og:description" content={description} />

View file

@ -65,10 +65,27 @@ export function createBaseConfig(
parallel: true, parallel: true,
sourceMap: false, sourceMap: false,
terserOptions: { terserOptions: {
ecma: 6, parse: {
mangle: true, // we want uglify-js to parse ecma 8 code. However, we don't want it
// to apply any minfication steps that turns valid ecma 5 code
// into invalid ecma 5 code. This is why the 'compress' and 'output'
// sections only apply transformations that are ecma 5 safe
// https://github.com/facebook/create-react-app/pull/4234
ecma: 8,
},
compress: {
ecma: 5,
warnings: false,
},
mangle: {
safari10: true,
},
output: { output: {
ecma: 5,
comments: false, comments: false,
// Turned on because emoji and regex is not minified properly using default
// https://github.com/facebook/create-react-app/issues/2488
ascii_only: true,
}, },
}, },
}), }),

View file

@ -88,7 +88,21 @@ export function getBabelLoader(isServer: boolean, babelOptions?: {}): Loader {
{ {
babelrc: false, babelrc: false,
configFile: false, configFile: false,
presets: ['@babel/env', '@babel/react'], presets: [
[
'@babel/env',
{
useBuiltIns: 'usage',
loose: true,
corejs: '2',
// Do not transform modules to CJS
modules: false,
// Exclude transforms that make all code slower
exclude: ['transform-typeof-symbol'],
},
],
'@babel/react',
],
plugins: [ plugins: [
isServer ? 'dynamic-import-node' : '@babel/syntax-dynamic-import', isServer ? 'dynamic-import-node' : '@babel/syntax-dynamic-import',
], ],

View file

@ -13,23 +13,23 @@ This means that if the site's `baseUrl` is `/`, an image in `/static/img/docusau
You can reference assets from the `static` folder in your code. You could use hardcoded absolute paths, i.e. starting with a slash /, but remember to include the `baseUrl` if it is not `/`. However, this will break if you change your `baseUrl` in the config. You can reference assets from the `static` folder in your code. You could use hardcoded absolute paths, i.e. starting with a slash /, but remember to include the `baseUrl` if it is not `/`. However, this will break if you change your `baseUrl` in the config.
A better way would be to use the `withBaseUrl` utility function which appends the `baseUrl` to paths for you. A better way would be to use the `useBaseUrl` utility function which appends the `baseUrl` to paths for you.
### JSX example ### JSX example
```jsx ```jsx
// MyComponent.js // MyComponent.js
import withBaseUrl from '@docusaurus/withBaseUrl'; import useBaseUrl from '@docusaurus/useBaseUrl';
<img <img
alt="Docusaurus with Keytar" alt="Docusaurus with Keytar"
src={withBaseUrl('img/docusaurus_keytar.svg')} src={useBaseUrl('img/docusaurus_keytar.svg')}
/>; />;
``` ```
### Markdown example ### Markdown example
Thanks to MDX, you can also use `withBaseUrl` utility function in Markdown files! You'd have to use `<img>` tags instead of the Markdown image syntax though. The syntax is exactly the same as in JSX. Thanks to MDX, you can also use `useBaseUrl` utility function in Markdown files! You'd have to use `<img>` tags instead of the Markdown image syntax though. The syntax is exactly the same as in JSX.
```txt ```txt
// my-doc.mdx // my-doc.mdx
@ -38,11 +38,11 @@ id: my-doc
title: My Doc title: My Doc
--- ---
import withBaseUrl from '@docusaurus/withBaseUrl'; // Add to the top of the file below the front matter. import useBaseUrl from '@docusaurus/useBaseUrl'; // Add to the top of the file below the front matter.
... ...
<img alt="Docusaurus with Keytar" src={withBaseUrl('img/docusaurus_keytar.svg')} />; <img alt="Docusaurus with Keytar" src={useBaseUrl('img/docusaurus_keytar.svg')} />;
``` ```
You could also just use Markdown image syntax, but you would have to manually maintain the image paths yourself and isn't recommended. You could also just use Markdown image syntax, but you would have to manually maintain the image paths yourself and isn't recommended.

View file

@ -9,7 +9,7 @@ import React, {useEffect} from 'react';
import Layout from '@theme/Layout'; import Layout from '@theme/Layout';
import Link from '@docusaurus/Link'; import Link from '@docusaurus/Link';
import withBaseUrl from '@docusaurus/withBaseUrl'; import useBaseUrl from '@docusaurus/useBaseUrl';
function Help() { function Help() {
return ( return (
@ -27,7 +27,7 @@ function Help() {
<h2>Browse the docs</h2> <h2>Browse the docs</h2>
<p> <p>
Learn more about Docusaurus using the{' '} Learn more about Docusaurus using the{' '}
<Link to={withBaseUrl('docs/introduction')}> <Link to={useBaseUrl('docs/introduction')}>
official documentation official documentation
</Link> </Link>
</p> </p>

View file

@ -8,7 +8,7 @@
import React from 'react'; import React from 'react';
import Link from '@docusaurus/Link'; import Link from '@docusaurus/Link';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import withBaseUrl from '@docusaurus/withBaseUrl'; import useBaseUrl from '@docusaurus/useBaseUrl';
import Image from '@theme/IdealImage'; import Image from '@theme/IdealImage';
import Layout from '@theme/Layout'; import Layout from '@theme/Layout';
@ -73,7 +73,7 @@ function Home() {
<img <img
alt="Docusaurus with Keytar" alt="Docusaurus with Keytar"
className={styles.heroLogo} className={styles.heroLogo}
src={withBaseUrl('img/docusaurus_keytar.svg')} src={useBaseUrl('img/docusaurus_keytar.svg')}
/> />
{siteConfig.title} makes it easy to maintain{' '} {siteConfig.title} makes it easy to maintain{' '}
<span className={styles.heroProjectKeywords}>Open Source</span>{' '} <span className={styles.heroProjectKeywords}>Open Source</span>{' '}
@ -82,7 +82,7 @@ function Home() {
<div className={styles.indexCtas}> <div className={styles.indexCtas}>
<Link <Link
className={styles.indexCtasGetStartedButton} className={styles.indexCtasGetStartedButton}
to={withBaseUrl('docs/introduction')}> to={useBaseUrl('docs/introduction')}>
Get Started Get Started
</Link> </Link>
<span className={styles.indexCtasGitHubButton}> <span className={styles.indexCtasGitHubButton}>
@ -105,14 +105,14 @@ function Home() {
Docusaurus 2 Docusaurus 2
</a> </a>
, contribute to its roadmap by suggesting features or giving feedback{' '} , contribute to its roadmap by suggesting features or giving feedback{' '}
<Link to={withBaseUrl('/feedback')}>here</Link>! <Link to={useBaseUrl('/feedback')}>here</Link>!
</div> </div>
</div> </div>
<div <div
className={classnames(styles.announcement, styles.announcementPrimary)}> className={classnames(styles.announcement, styles.announcementPrimary)}>
<div className={styles.announcementInner}> <div className={styles.announcementInner}>
Coming from v1? Check out our{' '} Coming from v1? Check out our{' '}
<Link to={withBaseUrl('/docs/migrating-from-v1-to-v2')}> <Link to={useBaseUrl('/docs/migrating-from-v1-to-v2')}>
v1 to v2 migration guide v1 to v2 migration guide
</Link> </Link>
. .
@ -125,7 +125,7 @@ function Home() {
<img <img
className={styles.featureImage} className={styles.featureImage}
alt="Powered by MDX" alt="Powered by MDX"
src={withBaseUrl('img/undraw_typewriter.svg')} src={useBaseUrl('img/undraw_typewriter.svg')}
/> />
<h3 className="padding-top--md">Powered by Markdown</h3> <h3 className="padding-top--md">Powered by Markdown</h3>
<p className="padding-horiz--md"> <p className="padding-horiz--md">
@ -139,7 +139,7 @@ function Home() {
<img <img
alt="Built Using React" alt="Built Using React"
className={styles.featureImage} className={styles.featureImage}
src={withBaseUrl('img/undraw_react.svg')} src={useBaseUrl('img/undraw_react.svg')}
/> />
<h3 className="padding-top--md">Built Using React</h3> <h3 className="padding-top--md">Built Using React</h3>
<p className="padding-horiz--md"> <p className="padding-horiz--md">
@ -152,7 +152,7 @@ function Home() {
<img <img
alt="Ready for Translations" alt="Ready for Translations"
className={styles.featureImage} className={styles.featureImage}
src={withBaseUrl('img/undraw_around_the_world.svg')} src={useBaseUrl('img/undraw_around_the_world.svg')}
/> />
<h3 className="padding-top--md">Ready for Translations</h3> <h3 className="padding-top--md">Ready for Translations</h3>
<p className="padding-horiz--md"> <p className="padding-horiz--md">
@ -168,7 +168,7 @@ function Home() {
<img <img
alt="Document Versioning" alt="Document Versioning"
className={styles.featureImage} className={styles.featureImage}
src={withBaseUrl('img/undraw_version_control.svg')} src={useBaseUrl('img/undraw_version_control.svg')}
/> />
<h3 className="padding-top--md">Document Versioning</h3> <h3 className="padding-top--md">Document Versioning</h3>
<p className="padding-horiz--md"> <p className="padding-horiz--md">
@ -181,7 +181,7 @@ function Home() {
<img <img
alt="Document Search" alt="Document Search"
className={styles.featureImage} className={styles.featureImage}
src={withBaseUrl('img/undraw_algolia.svg')} src={useBaseUrl('img/undraw_algolia.svg')}
/> />
<h3 className="padding-top--md">Document Search</h3> <h3 className="padding-top--md">Document Search</h3>
<p className="padding-horiz--md"> <p className="padding-horiz--md">