Strapi Permalinks/Canonical URLs/Slugs/Sitemaps

System Information
  • Strapi Version: 4.24

I’ve been diving into the integration of Strapi with Next.js, particularly in the context of deploying on platforms like Vercel. While the integration has been smooth overall, I’ve encountered a challenge regarding permalinks and canonical URLs that I’m hoping to discuss and find a solution for.

In essence, the issue stems from the read-only nature of the file system for public files on platforms like Vercel, which impedes the straightforward storage of a sitemap.xml. As a result, relying on a cached version becomes preferable.

I’ve explored various solutions, including the Strapi Sitemap plugin, which offers some capability in generating simple sitemaps. However, when it comes to handling nested categories and parent-child relationships to construct true canonical paths, I’ve hit a roadblock. It seems challenging, if not impossible, to build and maintain a comprehensive sitemap in such scenarios.

With the advent of the Next.js APP router, there’s increased flexibility in managing paths and dynamic routing. However, it appears that this flexibility isn’t fully supported on the Strapi sitemap side of the equation.

Moreover, there’s a notable disparity between the frontend’s reliance on routing and the backend’s relative ignorance of its location within the frontend’s path structure. Requesting Strapi for a permalink or canonical path would seemingly necessitate some intricate table magic, along with establishing relationships and leveraging lifecycle hooks.

What I find lacking in a so-called headless CMS like Strapi is the ability to provide the full URL of content. When URLs change, the absence of mechanisms to construct redirections on the frontend poses a challenge in ensuring that permanently moved or deleted content is appropriately handled.

One thing that also has been challenging is unique slugs across content types. One could follow the patterns of other CMSs by having posts with post types that would allow for one king content type for all the content types associated with posts/articles/pages/custom_page_types etc. So that one table (one content type) uuid slug uniqueness is detected across all content which can be displayed in a category(path depth), but again I see this as not a real scalable solution and leads to a very complex and bloated content-type (for all content) which feels like bad practice.

I firmly believe that the inherent flexibility of Strapi, coupled with the remarkable capabilities of modern frontend technologies, especially with caching options, can pave the way for an exceptional CMS experience. However, at present, I find a mix of documentation and plugins with limited use cases.

I’m reaching out to the community in the hopes of sparking a discussion and garnering insights, suggestions, or perhaps even shared experiences on how to address this challenge effectively. Any guidance, pointers to relevant resources, or shared experiences would be immensely appreciated.

Thank you

Hi @chris-barklem,

I’ve stumbled upon your post and wanted to shine some light on the current state of things in Strapi v5. While you might have moved on or found a solution, others reaching this post in the future might still need guidance on the topic.

While the things you’re asking for are not baked in to the core of Strapi, my team at PluginPal has built a plugin which hopefully fills most of the gaps called Strapi Webtools. In short it does the following things:

  1. It stores all the URLs for all content types in a single database table
  2. It can therefor provide uniqueness across all content types
  3. It offers a Router API endpoint to query any page based on its URL
  4. It’s modular setup allows for easy extension in the form of add-ons. We currently provide the following add-ons:
    a. Sitemap - Generate sitemaps based on the URLs
    b. Redirects - Automatically store a redirect when a URL changes
    c. Links - Dynamic links to pages in your Strapi app, either as a custom field or integrated in the Ckeditor
    d. Breadcrumbs - Fetch the page’s breadcrumbs, generated from it’s URL

Using this plugin you can create a nested URL structure by using the comprehensive URL pattern feature. That being said, I would love for you, or anyone else to try it out. If you’re looking for a demo, please feel free to reach us through our website.