Implementing preview functionality in Strapi CMS and Nuxt

Strapi CMS is an open-source content management system I implemented recently in one of my projects. Some parts of integrating Strapi with Nuxt were not well described, so I decided to share solutions I've done on my blog.

Why preview?

I work with some content creators publishing their content on a website I'm managing. One of them asked me if it was possible to see the preview of the content they are planning to publish.

Strapi by default doesn't provide that functionality. There is the possibility to see what Markdown content will look like, but assuming you implemented some extra formatting on your frontend, the end result can only be inspected there.

How to solve it?

I've found this plugin for Strapi called Preview Button.

Pasting here it's features:

  • Adds a new button in content manager sidebar which links the user to a preview or live view of a frontend app view.

  • Include optional button to copy the preview link to your clipboard.

  • Customize which content types should use the preview button.

  • Customize endpoints for draft and published URLs.

  • Map values from an entry's data into preview URLs.

  • Supports collection and single types.

  • Supports localization with the i18n Strapi plugin.

  • Optionally include preview and copy icons in list view.

These features were exactly what I needed, so I jumped into configuring it both in Strapi and in my Nuxt application.

IMPORTANT: This plugin only provides button in Strapi and opportunity to configure which link is preview and which is published. It's up to you to configure your frontend to present the preview. More about it later.

Strapi configuration

After following the installation instructions for Preview Button I started the configuration.

Here is my code from Strapi's plugin.ts.

  'preview-button': {
    config: {
      contentTypes: [
        {
          uid: 'api::content.content',
          draft: {
            url: 'https://yourwebsite.com/preview/content/{slug}',
          },
          published: {
            url: 'https://yourwebsite.com/content/{slug}',
          },
        },
      ],
    },
  },

That's it in Strapi, quite straightforward.

Nuxt configuration

In Nuxt I created a copy of my content directory in "preview" directory.

I use [slug].vue to dynamically decide on the page title and link.

As you can see the structure of my "pages" content is matching the link I provided in Strapi.

There is one significant difference between my published and preview content display. It's the way I search for the content, I need to add following parameter in order to display also drafts in Strapi's API:

publicationState=preview

So my whole search parameter looks like this right now.

const content = await find<ContentClass>('contents?publicationState=preview&filters[slug][$eq]=' + route.params.slug + '&populate=deep')

This way I can get my whole draft and present it as it would look like on my actual website.

Considerations

  • Make sure your drafts don't end up in your SEO by accident

    • In case you do use Server Side Rendering I would add it to excluded routes

    • I currently have Server Side Rendering turned off, so I don't need to worry (I think)

  • Make also sure that they are not available for visitors of your page before actually being published

    • In my case, there is no way a visitor can visit this page unless they guess the future article slug (fairly low chance ;) )