DEV Community

Christopher Wray
Christopher Wray

Posted on • Updated on

Displaying Markdown/ Strapi Rich Text in the Nuxt Frontend.

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.

Screenshot of markdown not parsed on the front end

Here, you can see that my content is all smashed together, even if I use v-html in the template tag. Also, the link is not a proper link.

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

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 };
  },
};

Enter fullscreen mode Exit fullscreen mode

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

Here is a screenshot of the markdown now:

Screenshot of Parsed Markdown

As you might notice, now, my content is nicely broken up into new paragraphs, and the link is a proper link 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.

Discussion (7)

Collapse
kwiat1990 profile image
Mateusz Kwiatkowski

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?

Collapse
cwraytech profile image
Christopher Wray Author

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.

Collapse
kwiat1990 profile image
Mateusz Kwiatkowski

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.

Thread Thread
cwraytech profile image
Christopher Wray Author

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.

Thread Thread
kwiat1990 profile image
Mateusz Kwiatkowski

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.

Thread Thread
cwraytech profile image
Christopher Wray Author • Edited

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./:

Collapse
chikalio profile image
Itheb Ben Abbes

i have images inside the rich text how to md that:( ?