DEV Community

Cover image for How to load and render Markdown files into your Vite React app using Typescript
Daniel
Daniel

Posted on

How to load and render Markdown files into your Vite React app using Typescript

Backstory (Skip it if you want)

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
Enter fullscreen mode Exit fullscreen mode

If you don’t use ChakraUI skip this step:

Install chakra-ui-markdown-renderer :

ChakraUI messes with the typical <h2> and other HTML stuff, so react-markdown won’t work unless we pass a custom renderer:

npm i chakra-ui-markdown-renderer
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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";
Enter fullscreen mode Exit fullscreen mode

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)};`;
        }
      }
    }
  ]
});
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

That’s it! You should see your markdown file rendered in all of its glory.

Hope these hours of research help someone. Cheers!

Top comments (1)

Collapse
 
alvarocavalcanti profile image
Alvaro Cavalcanti

Hey Daniel, thanks for the article! It got me unstuck on how to actually define the .md files as a module.

However, I'm not getting the file's content, instead I get export default "/store.md". Any clues?

The only difference in my code seems to be the ChakraUI bits.