6

Consider I have a folder with .md files like this:

/static/blog/
  example_title.md
  another_example.md
  three_examples.md

and I have an array including all titles:

const blogEntries = ["example_title", "another_example", "three_examples"]

in my component I want to import all of them, notice that there could be fewer or more.

Is there any way to dynamically import them similar to:

for (let entry in blogEntries) {
  import `Markdown_${entry}` from `/static/blog/${entry}.md`
}

and later in my render I can do:

<Markdown_three_examples />

the above obviously would not work, but I'm looking for a way to achieve similar.

supersize
  • 13,764
  • 18
  • 74
  • 133
  • When you build a react app, all your import / export stuff is converted into one big js file. There's no way to import stuff dynamically because babel can't build that into its file. The solution is to build a Markdown component and `fetch()` the md file from the server when it has mounted. –  Oct 23 '18 at 19:30
  • @ChrisG can you give an example as answer? – supersize Oct 23 '18 at 19:39
  • What part do you need help with? In `componentDidMount()`, use `fetch()` to load the Markdown file. Set its content as part of your state so it gets rendered. Implement the loop by rendering multiple components, using your file array and `map()`. –  Oct 23 '18 at 20:02
  • Two people have now suggested using `import()`, which is not required to do this at all, and imo takes the question strictly at face value while ignoring the bigger picture. Here's my take: https://codesandbox.io/s/l2jlq3j78m –  Oct 23 '18 at 20:20

3 Answers3

4

You can try to use dynamic imports - import(). As the name implies, they work during runtime, and can have dynamic urls.

Note: currently they are supported natively by Chrome and Safari, but not by firefox, IE, and Edge. However, you can use webpack to solve that.

const blogEntries = ["example_title", "another_example", "three_examples"]

const loadEntries = (entries) =>
  Promise.all(entries.map((entry) => import(`/static/blog/${entry}.md`)));

loadEntries(blogEntries)
  .then((entries) => console.log(entries));
Shinebayar G
  • 4,624
  • 4
  • 18
  • 29
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
  • I have following issue with this approach: ```WARNING in ./path/to/file/index.js 63:13-53 Critical dependency: the request of a dependency is an expression @ ./src/app.js``` @ ./src/server-entry.js – Aleksandr Ryabov May 02 '20 at 04:55
1
const Markdown = {}

for (let entry in blogEntries) {
  Markdown[entry] = require(`/static/blog/${entry}.md`)
}
Cyril Tan
  • 11
  • 1
0

Take a look at the following link. It's essentially used the external library - marked, fetching the content, then rendering the content to the screen. Essentially, you can call multiple fetches for each file needed and render the content dynamically.

How do I load a markdown file into a react component?

Note: There is a proposal in the ECMAScript standard for a dynamic import. You can read more about this here: https://developers.google.com/web/updates/2017/11/dynamic-import

Ross Sheppard
  • 850
  • 1
  • 6
  • 14
  • The question isn't about rendering markdown, it's about dynamically including static files. –  Oct 23 '18 at 19:58
  • Ah, but, as you can read, the OP wants to 'eventually' render Markdown. – Ross Sheppard Oct 23 '18 at 20:00
  • Sorry, but the dynamic import() only works when you use browser-side import/export. It won't work with React's babel transpilation. Plus it's Chrome-only, and experimental. –  Oct 23 '18 at 20:04
  • I'm glad you can. The question is not just about dynamic imports, but dynamic imports && markdown. To alleviate your concern, I edited my answer since at some point in the future, it is likely possible to import dynamically. – Ross Sheppard Oct 23 '18 at 20:07
  • Chris, as I said, it's a proposal that will most likely be adopted by the Babel and web browser community. – Ross Sheppard Oct 23 '18 at 20:08