docusaurus
docusaurus copied to clipboard
Getting invalid hooks error when loading markdown outside of docusaurs's root folder
Have you read the Contributing Guidelines on issues?
- [X] I have read the Contributing Guidelines on issues.
Prerequisites
- [X] I'm using the latest version of Docusaurus.
- [X] I have tried the
npm run clear
oryarn clear
command. - [X] I have tried
rm -rf node_modules yarn.lock package-lock.json
and re-installing packages. - [ ] I have tried creating a repro with https://new.docusaurus.io.
- [X] I have read the console error message carefully (if applicable).
Description
I don't think it is a Docusaurus problem itself but I'm missing some knowledge on internals to debug my situation.
When trying to import a file outside of the docusaurus folder in a monorepo like
/```mdx-code-block
import Contributingfrom "@site/../CONTRIBUTING.md"
<Contributing />
/```
I'm getting the basic invalid hook error
It is coming from the useMDXComponents
hooks apparently.
So I figured it was a dependency conflict with my monorepo. I can confirm it is a dependency problem by removing the packages to test this.
All my react/react-dom versions are identical, so it looks like it is a problem with react being loaded twice problem.
Since I'm only loading a plain markdown file, I don't understand why that would start conflicting. Do you have some pointers/recommendations to fix this?
Reproducible demo
No response
Steps to reproduce
I couldn't pinpoint the exact problem sadly and need some insights about how docusaurus might be import things
Expected behavior
No hooks error when loading md files outside of docusaurus folder
Actual behavior
Getting the invalid hook error.
Your environment
- Docusaurus version used:2.1.0
- Environment name and version (e.g. Chrome 89, Node.js 16.4): node 18
- Operating system and version (e.g. Ubuntu 20.04.2 LTS): mac os monterey
Self-service
- [x] I'd be willing to fix this bug myself.
Do you have a repo for me to clone? These kinds of errors are almost always dependency management faults, and without a repro it's hard to investigate.
Sure I pushed a branch on our monorepo so you can have a look :) https://github.com/strapi/strapi/tree/chore/transactions.
I pinpointed it into the helper-plugin package in packages/core. But couldn't find any real problem with the dependencies in there
Hi @Josh-Cena Would you have any pointers for me? Maybe some specific webpack config overwrites to force an alias for react to always be the same path 🤔
Hi @alexandrebodin , happy to see Strapi using Docusaurus (as I'm also French :p)
At first sight your issue to me is due to monorepo hoisting and using multiple versions of React in the monorepo.
If your imported MDX doc is at the root of your repo, it will likely use the hoisted version of React that you use on other projects
-
contributing.md
will usenode_modules/react
-
docs/contributing.md
will usedocs/node_modules/react
And then you end-up with 2 duplicate versions of React in the same project.
Unfortunately, I don't know how we can force the resolution to one version of React: that's how Node.js resolve dependency based on the location of files requiring them. I would advise to only import partials from your Docusaurus folder to avoid these problems.
To avoid duplicating the file, you can simply do cp contributing.md docs/contributing.md
as part of your npm install, and add the copy to gitignore? 🤷♂️
Another possibility would be to find a remark plugin that would allow you to "inline" the contributing doc md content inside your original md document: this way MDX will only build a single React component instead of having one React component importing another (which will import the bad React version).
Not sure it works but take a look at: https://github.com/dotansimha/remark-import-partial
Hope this makes sense
I ran into a similar issue, but not with mdx. Not sure if this would work for you, but adding this to plugins in docusaurus.config.js worked for me:
plugins: [
() => ({
name: 'resolve-react',
configureWebpack() {
return {
resolve: {
alias: {
// assuming root node_modules is up from "./packages/<your-docusaurus>
react: path.resolve('../../node_modules/react'),
},
},
};
},
}),
// ... other plugins
yes 👍 good solution
Wonder if we shouldn't add this in core to ensure Docusaurus users would at most use a single version of React
Although the path may vary depending on single repo vs more complex monorepo setups, it should be possible to find a solution and ref the React version Docusaurus is actually using
The proposed webpack config worked like a charm. Thanks for the tip 👍
I'm going to go ahead and close this issue now. Thank you for your help
@pdillon You saved my day, thanks!
It took me a while to track this issue down as the solution to my problem , I hope you don't mind if I dump a few search keywords:
docusaurus monorepo react component directory dependency
Invalid hook call. Hooks can only be called inside of the body of a function component.
Cannot read properties of null (reading 'useContext') (reading 'useState') (reading 'useEffect')