How to load and render Markdown files into your Vite React app using Typescript
Backstory (skipable)
Ok so I was REALLY struggling with this one.
I’m building an app, and for ease of use and maintenance, for the terms and conditions, privacy policy and other stuff I wanted to write them in markdown instead of plain TSX.
I could not find anything on my particular environment: Vite + React + Typescript + ChakraUI. So here’s what worked for me:
The solution
Test your markdown flow
First thing’s first, get your markdown rendering straight:
Install react-markdown
:
npm i react-markdown
If you don’t use ChakraUI skip this step:
Install chakra-ui-markdown-renderer
:
ChakraUI messes with the typical <h2> and stuff, so react-markdown
won’t work unless we pass a custom renderer:
npm i chakra-ui-markdown-renderer
Now create a simple component to test your markdown:
import { Box } from "@chakra-ui/react";
import ReactMarkdown from "react-markdown";
import ChakraUIRenderer from "chakra-ui-markdown-renderer";
const MarkdownTest = () => {
return (
<Box>
<ReactMarkdown
children={`# This is markdown!`}
components={ChakraUIRenderer()} // Skip this if you don't use ChakraUI
skipHtml // Skip this if you don't use ChakraUI
/>
</Box>
);
};
export default MarkdownTest;
You should see markdown when rendering this component. If so, let’s move on to how to import markdown files.
Importing Markdown Files
Now for the part I struggled with the most.
First we need to tell Typescript that markdown files are “importable” and not a usual module. Go to your vite-env.d.ts
and add this line:
declare module "*.md";
Cool? Cool.
Now we need to tell vite how to actually get the data inside of the markdown files. Go to your vite.config.ts
and create a custom plugin for this:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
react(),
// Custom plugin to load markdown files
{
name: "markdown-loader",
transform(code, id) {
if (id.slice(-3) === ".md") {
// For .md files, get the raw content
return `export default ${JSON.stringify(code)};`;
}
}
}
]
});
We’re almost there!!
Now go and create a markdown file, for instance test.md
.
In your component import it and add it and pass it to react markdown!!
import { Box } from "@chakra-ui/react";
import ReactMarkdown from "react-markdown";
import ChakraUIRenderer from "chakra-ui-markdown-renderer";
// Import markdown files
import markdown from 'test.md';
const MarkdownTest = () => {
return (
<Box>
<ReactMarkdown
// Pass it as children
children={markdown}
components={ChakraUIRenderer()} // Skip this if you don't use ChakraUI
skipHtml // Skip this if you don't use ChakraUI
/>
</Box>
);
};
export default MarkdownTest;
That’s it! You should see your markdown file rendered in all of its glory.
Hope these hours of research help someone. Cheers!