Ok, we've extracted
the logic to read the post file
in its own module.
But we're still reading the data
from a JSON file,
rather than from the Markdown file,
which was our ultimate goal.
To be able to use
the contents of this file
we need a way to parse the Markdown format
and transform it to HTML,
that we'll then insert into our page.
There are quite a few libraries
available in JavaScript
to work with Markdown.
In this example we'll use one
called "Marked",
that's very easy to use.
Let's see how it works.
For a start we'll need to
install that library,
so let me open the "package.json"
where we have our dependencies.
Let's open the terminal,
and stop the dev server,
because we need to run "npm install"
and download the "marked" package.
Ok. Now I want to show you quickly
how that library works,
and I'll do that by starting
an interactive Node prompt.
Let's start by importing the "marked" module,
and I'm using "require" instead of "import"
just because import statements
are still not supported
when running Node.js in this way.
But once we have the "marked" function
we can use it to generate some HTML
from a Markdown string.
Let's write a Markdown header for example,
and if we print that HTML,
you can see that it generated
an "h1" heading in HTML.
So it's very very simple to use.
Now let's restart our
Next.js dev server,
and let's go and use that library
to read Markdown files.
So in this file we first want to
import the "marked" function
from the module with the same name.
Now, reading the "data" from the file
will work in the same way,
except that we want to read
a Markdown file instead of a JSON one.
At this point we want to transform that "data",
that is a Markdown string,
to HTML using "marked".
And I think I'm going to rename this variable,
because "data" is a bit too vague.
Let's call it "source" instead,
as in, the Markdown source.
Now, we no longer need to parse any JSON,
but we still need to return
an object from here.
Because that's what we expect
where we use the post data.
If you remember in the page
we expect the "post"
to have a "title" and a "body".
So the "getPost" function should return
an object with those two properties.
But here we have a small problem,
in that we parse the Markdown
into a single "html" variable.
So we could return the "html"
as the "body" of the post.
But right now we don't really have
a separate "title" to return.
That's ok for now.
We'll see how to add metadata
to our Markdown file in the next video.
For the time being the "title"
will just be empty,
which is not ideal,
but shouldn't break anything.
So let's save these changes
and see what's being displayed
in the page now.
You can see that
it's clearly reading the content
from our Markdown file,
and converting it to HTML.
The problem is that
it's actually displaying the HTML source code,
rather than rendering it.
And that's because,
in our page component
we're currently displaying the "post.body"
as the child of a paragraph element.
So React will escape
any special HTML characters
contained in the "post.body" string.
But in this case we actually want to
insert the "post.body" directly as HTML.
So how can we do that?
Let's remove this paragraph,
since our "post.body" could potentially
contain multiple paragraphs.
Let's use an "article" element instead
to contain the "post.body",
which is semantically more appropriate.
Now, React provides a way
to insert HTML directly inside an element
by using a prop called
"dangerouslySetInnerHTML".
And it's called like that
because setting the HTML directly
can be dangerous from a security point of view.
If the HTML we're setting here
comes from content entered by our users,
they could use this to inject "scripts"
into our page.
But in this case we know that
the content always comes from
Markdown files that we wrote,
so it's not a problem here.
Now, to set this prop we need to pass
a JavaScript object,
that's inside a JSX expression,
so you end up with double curly braces.
This object must have a property
called "__html",
and this is where we pass
our "post.body" variable.
React makes this deliberately convoluted
because they want developers
to think very carefully
before setting the inner HTML directly.
Anyway, if we save this now,
you can see that the page displays
the content as we expected.
So it rendered the Markdown we had
in our post file
in a suitable way.
The Markdown header is shown
as a "h1" heading in the page,
the text within double underscores
is displayed as bold text,
and so on.
Ok. So now that we are finally
using the content from the Markdown file
we can delete this JSON file
that we wrote just as stepping stone.
To recap, we added the Marked library
to parse the Markdown into HTML,
and we're using "dangerouslySetInnerHTML"
to display that HTML directly into the page.