We are making progress! I now have the majority of the homepage done, and a good part of the Strapi backend.
For those of you just joining, this is a series through the process of building my personal portfolio with Nuxt, Strapi and TailwindCSS.
Now, I will write about displaying markdown/ or Strapi rich text attributes in the frontend.
Strapi has a rich text editor that generates markdown. If we want to display the markdown in the frontend, then we need to parse the markdown into HTML.
This looks pretty bad, so we need to parse the markdown correctly.
For my project, I decided to use an npm package, markdownit for this. It provided the fastest and most simple route of quickly parsing data on the front end and took less than 5 minutes to integrate into the site.
First, I installed the package by running:
yarn add @nuxtjs/markdownit
This added the package to my node_modules folder and added the package as a dependency in my package.json.
Then, I added the package to my nuxt.config.js file:
modules: [
'@nuxtjs/markdownit'
],
// This is for displaying rich text content in the frontend.
markdownit: {
preset: 'default',
linkify: true,
breaks: true,
injected: true
}
Then, I needed to parse the content in the Vue page component.
I needed to do this a little differently than what is described in the docs because I am parsing the data from the Strapi API on the Nuxt Server with asyncData().
In order to use the markdown package, I needed to pass $md into the asyncData() method, and use it to parse the markdown before passing it into the template.
Here is what my script tag in the Vue page component looks like after passing in $md and using it to render the markdown:
export default {
async asyncData({ $axios, $md }) {
//I am also using axios to get the content from the Strapi API.
const home = await $axios.$get("/home-page");
//This is where I use $md to parse the markdown for the example in the photos.
const content = $md.render(home.content);
const apiRoute = 'http://localhost:1337';
const heroImageUrl = apiRoute + home.hero_image.url;
const posts = await $axios.$get("/posts?_limit=4");
const projects = await $axios.$get("/projects?_limit=2");
const project = projects[0];
const projectImage = apiRoute + project.main_image.url;
const projectDescription = $md.render(project.description)
const secondProject = projects[1];
const secondProjectImage = apiRoute + secondProject.main_image.url;
const secondProjectDescription = $md.render(secondProject.description)
return {
home,
heroImageUrl,
posts,
content,
project,
projectImage,
projectDescription,
secondProject,
secondProjectImage,
secondProjectDescription };
},
};
As you may see, the part I am parsing is the home.content and the project descriptions.
You may also notice I built several other variables for accessing that data a little faster in the Vue Template.
Final Step
The last thing I needed to do, is make sure that my template in the Vue page component was properly referencing the data.
For the home content it looks like this:
<div class="prose prose-lg text-gray-500 mx-auto"
v-if="content"
v-html="content"></div>
Here is a screenshot of the markdown now:
Well, that is how you parse markdown in Nuxt! Would love to know your thoughts. Anything you would do differently?
You can also look at my portfolio frontend code here, and the backend Strapi application here.
Top comments (8)
Hi Christopher, did you managed somehow to transform all links, which are used in rich text and then parsed with markdown, to a router-link if they point to internal pages or they stay just a normal instead and trigger a page reload?
That’s a really good next step! At this point they just stay normal links and do a full page load. My site is statically generated though so it doesn’t slow it down too much.
My site will be as well but I think it's suboptimal to have a router links all around the place and only in content from Strapi not. Sadly the way Strapi deals with rich text is far away from what's I would call flexible and good. I would love to have something like the rich text schema from Prismic. The way it is structured let you make whole bunch of stuff before (manipulating HTML elements and its properties is easy) it will be rendered.
One thing that you can do is use html for internal links and write Nuxt links that way in Strapi. The markdown parser that I used in this blog lets you allow html as well.
I do agree that the rich text in Strapi is not enjoyable.
My stack includes Gridsome instead of Nuxt.
I have tried to take advantage of the
postrender
function, which markdown parser offers, but Vue can't parsed the code correctly, so a router-link will be rendered direct in DOM. Instead I need to try to build some sort of wrapper component, which use Vue render function. Then hopefully it should work.What's bother me also is the fact, that without any structure for rich text content it is (almost I guess) impossible to build any complicated layout, which would involve some CSS usage. It seems like Strapi want to make the content so simple as possible and tend to prefer stack layout, which make sense especially on mobile.
Actually, you can use dynamic fields in Strapi to build pretty complex layouts! You should check out the Strapi tutorials.
Like I said though before I do agree that the Rich text is not very nice./:
i have images inside the rich text how to md that:( ?
Waw, this is what I was looking for. thanks chris