[` as documented in [the basic cheatsheet](https://github.com/typescript-cheatsheets/react/blob/main/README.md#forwardrefcreateref), but we are interested in more real world examples. [Here is a nice example in practice](https://gist.github.com/OliverJAsh/d2f462b03b3e6c24f5588ca7915d010e) from @OliverJAsh (note - it still has some rough edges, we need help to test this out/document this).
-
-### Supporting `defaultProps` of Wrapped Component
-
-If this is something you need, please see [the stale discussion we had](https://github.com/typescript-cheatsheets/react/issues/86) and comment with your requirements. We will pick this up again if needed.
diff --git a/docs/hoc/index.md b/docs/hoc/index.md
deleted file mode 100644
index 5803667e0..000000000
--- a/docs/hoc/index.md
+++ /dev/null
@@ -1,65 +0,0 @@
----
-id: intro
-sidebar_label: Intro
-title: HOC Cheatsheet
----
-
-**This HOC Cheatsheet** compiles all available knowledge for writing Higher Order Components with React and TypeScript.
-
-- We will map closely to [the official docs on HOCs](https://reactjs.org/docs/higher-order-components.html) initially
-- While hooks exist, many libraries and codebases still have a need to type HOCs.
-- Render props may be considered in the future
-- The goal is to write HOCs that offer type safety while not getting in the way.
-
-There are a lot of use cases where an HOC is used. For example:
-
-- HOCs can wrap components to check if a user is authenticated before rendering, or to restrict access based on user roles.
-- An HOC can conditionally render components based on feature flags or A/B testing.
-- An HOC can provide translation functionality to components.
-- An HOC can add logging or analytics tracking to components without modifying their core logic.
-
-Here is a base HOC example you can copy right away:
-
-```tsx
-type PropsAreEqual] = (
- prevProps: Readonly
,
- nextProps: Readonly
-) => boolean;
-
-const withSampleHoC =
(
- component: {
- (props: P): Exclude;
- displayName?: string;
- },
- propsAreEqual?: PropsAreEqual | false,
-
- componentName = component.displayName ?? component.name
-): {
- (props: P): React.JSX.Element;
- displayName: string;
-} => {
- function WithSampleHoc(props: P) {
- //Do something special to justify the HoC.
- return component(props) as React.JSX.Element;
- }
-
- WithSampleHoc.displayName = `withSampleHoC(${componentName})`;
-
- let wrappedComponent =
- propsAreEqual === false
- ? WithSampleHoc
- : React.memo(WithSampleHoc, propsAreEqual);
-
- //copyStaticProperties(component, wrappedComponent);
-
- return wrappedComponent as typeof WithSampleHoc;
-};
-```
-
-This code meets these criteria:
-
-1. Allows a component to return valid elements (`strings | array | boolean | null | number`) and not just `React.JSX.Element | null`.
-2. Wraps it in a memo unless you opt out.
-3. Removes the nested component, so React Dev tools will just show one component.
-4. Indicates with `displayName` in React Dev Tool with an annotation that this is a component wrapped in two HoCs
-5. Optional: Copies over static properties that might have been defined on the original component.
diff --git a/docs/hoc/react-hoc-docs.md b/docs/hoc/react-hoc-docs.md
deleted file mode 100644
index 6a099dd05..000000000
--- a/docs/hoc/react-hoc-docs.md
+++ /dev/null
@@ -1,297 +0,0 @@
----
-id: react_hoc_docs
-sidebar_label: React HOC docs in TypeScript
-title: "Section 1: React HOC docs in TypeScript"
----
-
-In this first section we refer closely to [the React docs on HOCs](https://reactjs.org/docs/higher-order-components.html) and offer direct TypeScript parallels.
-
-## Docs Example: [Use HOCs For Cross-Cutting Concerns](https://reactjs.org/docs/higher-order-components.html#use-hocs-for-cross-cutting-concerns)
-
-
-
-
-Misc variables referenced in the example below
-
-
-```tsx
-/** dummy child components that take anything */
-const Comment = (_: any) => null;
-const TextBlock = Comment;
-
-/** dummy Data */
-type CommentType = { text: string; id: number };
-const comments: CommentType[] = [
- {
- text: "comment1",
- id: 1,
- },
- {
- text: "comment2",
- id: 2,
- },
-];
-const blog = "blogpost";
-
-/** mock data source */
-const DataSource = {
- addChangeListener(e: Function) {
- // do something
- },
- removeChangeListener(e: Function) {
- // do something
- },
- getComments() {
- return comments;
- },
- getBlogPost(id: number) {
- return blog;
- },
-};
-/** type aliases just to deduplicate */
-type DataType = typeof DataSource;
-// type TODO_ANY = any;
-
-/** utility types we use */
-type Omit = Pick>;
-// type Optionalize = Omit;
-
-/** Rewritten Components from the React docs that just uses injected data prop */
-function CommentList({ data }: WithDataProps) {
- return (
-
- {data.map((comment: CommentType) => (
-
- ))}
-
- );
-}
-interface BlogPostProps extends WithDataProps {
- id: number;
-}
-function BlogPost({ data, id }: BlogPostProps) {
- return (
-
- ;
-
- );
-}
-```
-
-[View in TypeScript Playground](https://www.typescriptlang.org/play/?jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wFgAoCgeirhgAskBnJOFIuxuMHMJuiHABGrYADsAVkgxIAJsICenVgAkA8gGEK4mEiiZ0rAOrAGAERQwUABV5MAPABUAfHADeFOHFmWUALjhHAG44Gm9fOGB+AHMkMT1gNAoAX2paR0j+BlYYBTBWCExwqzS4a0zlbjs4QsqAdygUMHz5NFxIeLF4BksK8Uw9IllSjQrstgwAVxQAG0iuvQM0AqLxhqaWuDbwCE74AApJlnkYQWjGoW8kA0mZmFsIPjhsXEiYAEoKJAAPSFhnyZiDDAXZwOqmegAZUmQiYaCgwDAMBBYicABoynAfroxLJ+CZzL4HnwnM4MRpnPtPKFaAwonQ8qxZjMIHV+EcBPMBlAyhihJN4OcUJdxrl8jUikZGs05Bp2rs4vAWGB2JYkDMlOCGBABW95rp9AkxNEwRDKv09HFlhKytSpRtZfK9gFkOgYAA6ABSkIAGgBRGZIECKuViJgwKCTDDQezWVwAMjgGjR1LCLEDGAsVgqKABQNOPMw0ECqdoPEe-Hprtkuw1wmkKCOohg+H4RBQNbEdfETGAshWlTQMxQTCY1PT0hgWf8cCp5C8Xh8VkhOqgywCYqQtWnK8ma6QKfnC-LfBdqE7Gvs3p97oAMsAhI0oAoALIoMQoWKyACCMAjD4FZh7GTOA1BAUxYwxAAiJcUCg5wEOpd44AAXlcRwKGQjwjzCcYQE-RIKkYIgAmvO8HyfV930-ORf3-fldH4cEZjmKwAGsci4TcbXtFo5R2PY2FxOAiCYCAZgAN2bfh+xuO4qgrUs2GiFAe26LgT34WoCXoacMTqehEnoCoJCOdSCgRaJxFmTFuK1Yz8Fg-ARKDCApPkF48FMNskAAR0mYAiGDLoxyPbjiX4FC4DI+9H3YKiPy-OiEQYoCQLAiDrGg2D4OcIJqW4yErF0VD3GpRdfACYJqWSfKjyIGA9zELZh1HOAdOnLFvhxPFEGID1+I6RVYzsDEirVVxsIXLZdnDSNoygfZNICCKsPKhcmEmfJFs0946umrw6SYd16HfWRAw0U7jVYKKjpOs6Lqu2J3SEcRZH2I69vWw7DOO8M1VKqaDoqqwAgnTNfH2HdV2WDFdu+uBavW1JKCPLxtiGrozD7F8dS6Ur9mQtC4GhvdlndDtZEu99YnvcM4j0D7fvu3FHpppAvtR6aMYVLoTBYgBVMQQDx+AosJ1DnAR0n93dIK3KQanrrpnFGbuq7zsVp6Obq9aNbZ66CaJqW0YXO6WBgcbdH2IHgdgsH1Unacod8Xd9wxO74dNrxkk59aiFxRm1u9mlKjFcQTSLHkmB4c8I84KJ3U0zJ3VTuApOfGbwEDb53XrcMwRQJRLPoeAxFZMZBFMgvuNMNh+HfBQEbCWDTRYuBw2AduRAZfI0EYNAOOGEOGqa2cEa8exeL4p1FWKFAULcc3iqQd1YOSdxU-dJnE+TkchIUd4N6oE3gc56aUZ9-bQ9HqBmo63w6pR6gACoX7gdRRiOGjTQYJNZ5CnAF+VAvi-GgPANoYZ4D8WCjAFWOloSwnhIiZEoIor2UQXCBESIURzi8DAxUKtDxeBdsuGGSAAjTkcIyY2JNXbkPdLEGABCQqE0wrrcgPw-gQNmvAAAQiyaI1gIDhgQTCLBKCUSlQweI5BODdh4LgAIiAQiREwGIbOGW646FWGofkOGdgAgZRgPYZRqjwwRWyr4eCxt1paNXkwsxwjwxLTsO6PsnxyB7SAA)
-
-
-
-Example HOC from React Docs translated to TypeScript
-
-```tsx
-// these are the props to be injected by the HOC
-interface WithDataProps {
- data: T; // data is generic
-}
-// T is the type of data
-// P is the props of the wrapped component that is inferred
-// C is the actual interface of the wrapped component (used to grab defaultProps from it)
-export function withSubscription, C>(
- // this type allows us to infer P, but grab the type of WrappedComponent separately without it interfering with the inference of P
- WrappedComponent: React.JSXElementConstructor & C,
- // selectData is a functor for T
- // props is Readonly because it's readonly inside of the class
- selectData: (
- dataSource: typeof DataSource,
- props: Readonly>>
- ) => T
-) {
- // the magic is here: React.JSX.LibraryManagedAttributes will take the type of WrapedComponent and resolve its default props
- // against the props of WithData, which is just the original P type with 'data' removed from its requirements
- type Props = React.JSX.LibraryManagedAttributes>;
- type State = {
- data: T;
- };
- return class WithData extends React.Component {
- constructor(props: Props) {
- super(props);
- this.handleChange = this.handleChange.bind(this);
- this.state = {
- data: selectData(DataSource, props),
- };
- }
-
- componentDidMount = () => DataSource.addChangeListener(this.handleChange);
-
- componentWillUnmount = () =>
- DataSource.removeChangeListener(this.handleChange);
-
- handleChange = () =>
- this.setState({
- data: selectData(DataSource, this.props),
- });
-
- render() {
- // the typing for spreading this.props is... very complex. best way right now is to just type it as any
- // data will still be typechecked
- return (
-
- );
- }
- };
- // return WithData;
-}
-
-/** HOC usage with Components */
-export const CommentListWithSubscription = withSubscription(
- CommentList,
- (DataSource: DataType) => DataSource.getComments()
-);
-
-export const BlogPostWithSubscription = withSubscription(
- BlogPost,
- (DataSource: DataType, props: Omit) =>
- DataSource.getBlogPost(props.id)
-);
-```
-
-## Docs Example: [Don’t Mutate the Original Component. Use Composition.](https://reactjs.org/docs/higher-order-components.html#dont-mutate-the-original-component-use-composition)
-
-This is pretty straightforward - make sure to assert the passed props as `T` [due to the TS 3.2 bug](https://github.com/Microsoft/TypeScript/issues/28938#issuecomment-450636046).
-
-```tsx
-function logProps(WrappedComponent: React.ComponentType) {
- return class extends React.Component {
- componentWillReceiveProps(
- nextProps: React.ComponentProps
- ) {
- console.log("Current props: ", this.props);
- console.log("Next props: ", nextProps);
- }
- render() {
- // Wraps the input component in a container, without mutating it. Good!
- return ;
- }
- };
-}
-```
-
-## Docs Example: [Pass Unrelated Props Through to the Wrapped Component](https://reactjs.org/docs/higher-order-components.html#convention-pass-unrelated-props-through-to-the-wrapped-component)
-
-No TypeScript specific advice needed here.
-
-## Docs Example: [Maximizing Composability](https://reactjs.org/docs/higher-order-components.html#convention-maximizing-composability)
-
-HOCs can take the form of Functions that return Higher Order Components that return Components.
-
-`connect` from `react-redux` has a number of overloads you can take inspiration [from in the source](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/bc0c933415466b34d2de5790f7cd6418f676801e/types/react-redux/v5/index.d.ts#L77).
-
-Here we build our own mini `connect` to understand HOCs:
-
-
-
-
-Misc variables referenced in the example below
-
-
-```tsx
-/** utility types we use */
-type Omit = Pick>;
-
-/** dummy Data */
-type CommentType = { text: string; id: number };
-const comments: CommentType[] = [
- {
- text: "comment1",
- id: 1,
- },
- {
- text: "comment2",
- id: 2,
- },
-];
-/** dummy child components that take anything */
-const Comment = (_: any) => null;
-/** Rewritten Components from the React docs that just uses injected data prop */
-function CommentList({ data }: WithSubscriptionProps) {
- return (
-
- {data.map((comment: CommentType) => (
-
- ))}
-
- );
-}
-```
-
-
-
-```tsx
-const commentSelector = (_: any, ownProps: any) => ({
- id: ownProps.id,
-});
-const commentActions = () => ({
- addComment: (str: string) =>
- comments.push({ text: str, id: comments.length }),
-});
-
-const ConnectedComment = connect(commentSelector, commentActions)(CommentList);
-
-// these are the props to be injected by the HOC
-interface WithSubscriptionProps {
- data: T;
-}
-function connect(mapStateToProps: Function, mapDispatchToProps: Function) {
- return function , C>(
- WrappedComponent: React.ComponentType
- ) {
- type Props = React.JSX.LibraryManagedAttributes>;
- // Creating the inner component. The calculated Props type here is the where the magic happens.
- return class ComponentWithTheme extends React.Component {
- public render() {
- // Fetch the props you want inject. This could be done with context instead.
- const mappedStateProps = mapStateToProps(this.state, this.props);
- const mappedDispatchProps = mapDispatchToProps(this.state, this.props);
- // this.props comes afterwards so the can override the default ones.
- return (
-
- );
- }
- };
- };
-}
-```
-
-[View in TypeScript Playground](https://www.typescriptlang.org/play/?jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wFgAoCtCAOwGd5qQQkaY64BeOAbQF0A3BSq0GcAMK4WbADLAx3ABQBKLgD44iinDgAeACbAAbnAD0aisuHlq9RlNYwAykgA2SDNC6aA+gC44FBoATwAaOAgAdxoABRwwOgCg4NVODUUAb204YH0AqNj4ugA6XIoAX2UhG1F7ZkcAQQxgUW8VdU0s8h0UfX1JerYAxQYoANHgGgBzVI0maXZisABXOgALTLgYJAAPGHGYKHDcgPnHEvdpmDW4Soqq61sxSRoaD23+hzZvWzeMLW6cDObBc7k8R2ywJgTRgLXolkUAwWcgYD0o5FMpi2ayQdCQgSI2PxYCKWwgcAARvjJgArd5IfSU4JEuAACQA8uIKJNtlBMOh8QB1YDXJzLCl0NBQYBgWG0OIQBK6AAqGi6On0KBgKACyuq5QomGWNGatCBtD+MEUIBQYCc2u2yogCoSAQAYsbTTRwjawAAReRgLVoNZOl2JOAek1ymiqdVwIgwZZQGhwI3RuEq8IxOC7bY0fQcYWi8WS6WyuHhlVqcLiNQAnQ6QVQW1gBkDSBvIaIYgwYod2iOZXBNvV7Jx7I6GAj-Hh7wAKScAA1inIKS2oMEALJBFBTBkNGCHYAU5bbOi6cThdkgEW6GLhABEmu1j7UamqjbMWPERC1kymFlJjeKBzXAQc2GKOBlRxIEUFcNBllcLUGTgOdpzbOAcUJeQWUibD8WufEbSmYA0Cw1tWBKScEyQJMUyBZC6A4AcuxgYtQxxFhcz2VhCx7dA+1Yxx7yKNUaJ0FYKVcMjaILJAoHaeMvx0TFIzokMWRJRUOGCCBljgSIgngWl3igmDcOoJDGSpOB9EHQyRRuWxtj2HI7FQfRigkxsnngX0230e0ULnbhfWCx1nSKRRrnkYoGBQ8JYpKbSEjRFTfNqOAAoZAM6CDGAQ1C7LbTygqQzDaLkvih0kCStY4tSuh0oy79sUa0kmFxQJMF5IyoH4uhySIuDUwgIwFOlfRCNg6b+SQ+BB2owEMsTZNUwbVqdF0ZtKM+cC2J8jKMmKU7qqag0Vq2uATtOnKgtq8NLuuxtbuKe6yuDNYnqOxtzF+lqv2extyk-W59SAA)
-
-## Docs Example: [Wrap the Display Name for Easy Debugging](https://reactjs.org/docs/higher-order-components.html#convention-wrap-the-display-name-for-easy-debugging)
-
-This is pretty straightforward as well.
-
-```tsx
-interface WithSubscriptionProps {
- data: any;
-}
-
-function withSubscription<
- T extends WithSubscriptionProps = WithSubscriptionProps,
->(WrappedComponent: React.ComponentType) {
- class WithSubscription extends React.Component {
- /* ... */
- public static displayName = `WithSubscription(${getDisplayName(
- WrappedComponent
- )})`;
- }
- return WithSubscription;
-}
-
-function getDisplayName(WrappedComponent: React.ComponentType) {
- return WrappedComponent.displayName || WrappedComponent.name || "Component";
-}
-```
-
-## Unwritten: [Caveats section](https://reactjs.org/docs/higher-order-components.html#caveats)
-
-- Don’t Use HOCs Inside the render Method
-- Static Methods Must Be Copied Over
-- Refs Aren’t Passed Through
diff --git a/docs/react-types/index.md b/docs/react-types/index.md
deleted file mode 100644
index 4d86ede51..000000000
--- a/docs/react-types/index.md
+++ /dev/null
@@ -1,10 +0,0 @@
----
-title: React Types
----
-
-`@types/react`Â makes some types available that can be very useful. Here's a list in alphabetical order with links to the detailed reference pages.
-
-- [`ComponentProps`](/docs/react-types/ComponentProps)
-- [`CSSProperties`](/docs/react-types/CSSProperties)
-- [`ReactNode`](/docs/react-types/ReactNode)
-- [`Ref`, `RefObject`, `RefCallback`](/docs/react-types/Ref)
diff --git a/docs/react-types/CSSProperties.md b/docs/reference/CSSProperties.md
similarity index 100%
rename from docs/react-types/CSSProperties.md
rename to docs/reference/CSSProperties.md
diff --git a/docs/react-types/ComponentProps.md b/docs/reference/ComponentProps.md
similarity index 100%
rename from docs/react-types/ComponentProps.md
rename to docs/reference/ComponentProps.md
diff --git a/docs/react-types/ReactNode.md b/docs/reference/ReactNode.md
similarity index 97%
rename from docs/react-types/ReactNode.md
rename to docs/reference/ReactNode.md
index 960c427cf..92ad51342 100644
--- a/docs/react-types/ReactNode.md
+++ b/docs/reference/ReactNode.md
@@ -124,5 +124,3 @@ const MyComponent = () => "hello";
// 👍 explicit
const MyComponent = (): React.JSX.Element => hello;
```
-
-[Something to add? File an issue](https://github.com/typescript-cheatsheets/react/issues/new).
diff --git a/docs/react-types/Ref.md b/docs/reference/Ref.md
similarity index 100%
rename from docs/react-types/Ref.md
rename to docs/reference/Ref.md
diff --git a/genReadme.mjs b/genReadme.mjs
index 64640b514..cef250f70 100644
--- a/genReadme.mjs
+++ b/genReadme.mjs
@@ -164,7 +164,6 @@ async function main(argv) {
path: "docs/basic/setup.md",
withToc: true,
relativeHeadingLevel: 1,
- prefix: "Section 1: ",
});
pendingReadme = await updateSectionWith({
from: currentReadme,
@@ -233,14 +232,6 @@ async function main(argv) {
name: "concurrent",
path: "docs/basic/getting-started/concurrent.md",
});
- pendingReadme = await updateSectionWith({
- from: currentReadme,
- to: pendingReadme,
- name: "linting",
- path: "docs/basic/linting.md",
- relativeHeadingLevel: 1,
- });
-
const prettierConfig = await prettier.resolveConfig(readmePath);
pendingReadme = await prettier.format(pendingReadme, {
...prettierConfig,
diff --git a/package.json b/package.json
index 9bdd7b673..cdbe53c0b 100644
--- a/package.json
+++ b/package.json
@@ -28,7 +28,8 @@
"postinstall": "cd website && yarn",
"prepare": "husky",
"start": "yarn --cwd website start",
- "build": "yarn --cwd website build"
+ "build": "yarn --cwd website build",
+ "serve": "yarn --cwd website serve"
},
"dependencies": {
"front-matter": "^4.0.2",
diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js
index 3a6d7b0d1..75efb842e 100644
--- a/website/docusaurus.config.js
+++ b/website/docusaurus.config.js
@@ -14,9 +14,9 @@ const setupDoc = "docs/basic/setup";
module.exports = {
favicon: "img/icon.png",
- title: "React TypeScript Cheatsheets", // Title for your website.
+ title: "React TypeScript Cheatsheet", // Title for your website.
tagline:
- "Cheatsheets for experienced React developers getting started with TypeScript",
+ "A cheatsheet for experienced React developers getting started with TypeScript",
url: "https://react-typescript-cheatsheet.netlify.app", // Your website URL
baseUrl: "/",
projectName: "react-typescript-cheatsheet",
@@ -102,14 +102,6 @@ module.exports = {
label: "Introduction",
to: setupDoc,
},
- {
- label: "High Order Component (HOC)",
- to: "docs/hoc",
- },
- {
- label: "Advanced Guides",
- to: "docs/advanced",
- },
],
},
{
diff --git a/website/package.json b/website/package.json
index 4163c21af..d7da3db54 100644
--- a/website/package.json
+++ b/website/package.json
@@ -3,6 +3,7 @@
"add-pages-on-site": "node ../copyFile.js",
"start": "yarn add-pages-on-site && docusaurus start",
"build": "yarn add-pages-on-site && docusaurus build",
+ "serve": "docusaurus serve",
"swizzle": "docusaurus swizzle",
"deploy": "yarn add-pages-on-site && docusaurus deploy"
},
diff --git a/website/sidebars.json b/website/sidebars.json
index 8ae75091e..7490183d4 100644
--- a/website/sidebars.json
+++ b/website/sidebars.json
@@ -1,38 +1,33 @@
{
- "docs": {
- "Basic": [
- "basic/setup",
- {
- "type": "category",
- "label": "Getting Started",
- "items": [
- "basic/getting-started/basic_type_example",
- "basic/getting-started/function_components",
- "basic/getting-started/hooks",
- "basic/getting-started/class_components",
- "basic/getting-started/default_props",
- "basic/getting-started/forms_and_events",
- "basic/getting-started/context",
- "basic/getting-started/forward_and_create_ref",
- "basic/getting-started/portals",
- "basic/getting-started/error_boundaries",
- "basic/getting-started/concurrent"
- ]
- },
- "basic/linting"
- ],
- "HOC": [
- "hoc/intro",
- "hoc/full_example",
- "hoc/react_hoc_docs",
- "hoc/excluding_props"
- ],
- "Advanced": [
- "advanced/intro",
- "advanced/utility_types",
- "advanced/patterns_by_usecase",
- "advanced/misc_concerns",
- "advanced/types_react_api"
- ]
- }
+ "docs": [
+ "basic/setup",
+ {
+ "type": "category",
+ "label": "Learn",
+ "items": [
+ "basic/getting-started/basic_type_example",
+ "basic/getting-started/function_components",
+ "basic/getting-started/hooks",
+ "basic/getting-started/class_components",
+ "basic/getting-started/default_props",
+ "basic/getting-started/forms_and_events",
+ "basic/getting-started/context",
+ "basic/getting-started/forward_and_create_ref",
+ "basic/getting-started/portals",
+ "basic/getting-started/error_boundaries",
+ "basic/getting-started/concurrent",
+ "basic/getting-started/patterns_by_usecase"
+ ]
+ },
+ {
+ "type": "category",
+ "label": "API Reference",
+ "items": [
+ "reference/ComponentProps",
+ "reference/CSSProperties",
+ "reference/ReactNode",
+ "reference/Ref"
+ ]
+ }
+ ]
}
diff --git a/website/src/pages/index.js b/website/src/pages/index.js
index 354cf6715..b519a5c23 100644
--- a/website/src/pages/index.js
+++ b/website/src/pages/index.js
@@ -9,9 +9,9 @@ export default function Home() {
const { siteConfig } = useDocusaurusContext();
return (