RedneckWorks
FULLSTACK ENGINEERING
AngularJavaDockerJenkins
Dynamic XML Sitemap with Spring Boot and Contentful Instead of Angular

Dynamic XML Sitemap with Spring Boot and Contentful Instead of Angular

Discover why I generate my XML sitemap with Spring Boot instead of Angular. New Contentful articles automatically appear in the sitemap without rebuilding or redeploying the frontend, making the architecture cleaner, more scalable, and easier to maintain.


πŸ’‘ The Starting Point

When I started building my project, the sitemap.xml was generated by the Angular frontend.For a small website, this approach works perfectly fine. However, as the number of articles grew, one major drawback became obvious. Every new article required:

  • πŸ”¨ a new Angular build

  • 🐳 a new Docker image

  • πŸš€ a frontend deployment

  • πŸ” only then could Google discover the new article through the updated sitemap

Even though nothing in the frontend had actually changed.That was the moment I started questioning the architecture.


❓ Who Should Own the Sitemap?

A sitemap only describes the content of a website. But the content itself does not come from Angular. It is managed entirely in Contentful and already processed by the Spring Boot backend. So I asked myself one simple question:

Why should the frontend generate the sitemap when the backend already owns all the data?


πŸ—οΈ The Original Architecture

The original content flow looked like this:

Contentful ↓ Spring Boot API ↓ Angular SSR

Angular SSR was then responsible for two separate outputs:

  • 🌐 Rendering the HTML pages

  • πŸ—ΊοΈ Providing the static sitemap.xml

This meant the frontend was responsible for both rendering the application and generating SEO-related files.

The result was an unnecessary dependency between content publishing and frontend deployment.


πŸš€ The New Architecture

I moved the entire sitemap generation into the Spring Boot backend.

The backend already knows everything required to build a valid XML sitemap:

  • πŸ“„ Every published article

  • 🌍 Every available language version

  • πŸ“… Publication and last update dates

  • πŸ”— Every public URL

Because of that, the backend can generate the sitemap dynamically without any help from the frontend.

The new architecture is much simpler:

Contentful ⬇️ Spring Boot

Spring Boot now provides two independent outputs:

  • πŸ”Œ REST API

  • πŸ—ΊοΈ Dynamic sitemap.xml

The sitemap is delivered directly to search engines through Traefik, while Angular SSR is responsible only for rendering the user interface.

The frontend no longer has any SEO-related responsibility. Publishing a new article automatically updates the sitemap without rebuilding or redeploying Angular.


βš™οΈ The Entry Point

The entire XML sitemap is exposed through a dedicated REST endpoint. The controller itself contains no business logic. Its only responsibility is to delegate the request to the service layer.

@RestController
public class SitemapController {

    private final SitemapService sitemapService;

    public SitemapController(SitemapService sitemapService) {
        this.sitemapService = sitemapService;
    }

    @GetMapping(
        value = "/sitemap.xml",
        produces = "application/xml"
    )
    public ResponseEntity<String> getSitemap() {
        return ResponseEntity.ok(
            sitemapService.generateSitemap()
        );
    }
}

βš™οΈ How It Works Today

The entire publishing process is now fully automated.

  1. ✍️ Publish an article in Contentful

  2. πŸ”„ Spring Boot retrieves the new content

  3. πŸ—ΊοΈ The XML sitemap is updated automatically

  4. πŸ€– Google discovers the new URL during its next sitemap crawl

There is:

  • ❌ no Angular build

  • ❌ no frontend Docker image

  • ❌ no frontend deployment

Only the content changes.The infrastructure remains untouched.


πŸ“‹ What the Sitemap Contains

The generated sitemap automatically includes:

  • βœ… all static pages

  • βœ… all blog articles

  • βœ… lastmod

  • βœ… hreflang

    links for English and German

  • βœ… SEO-friendly URLs

The sitemap always reflects the current state of the website.

<url>
    <loc>
        https://redneckworks.bielski.nrw/en/blog/dynamic-xml-sitemap
    </loc>

    <lastmod>2026-07-23</lastmod>

    <xhtml:link
        rel="alternate"
        hreflang="de"
        href="https://redneckworks.bielski.nrw/de/blog/dynamic-xml-sitemap"/>

    <xhtml:link
        rel="alternate"
        hreflang="en"
        href="https://redneckworks.bielski.nrw/en/blog/dynamic-xml-sitemap"/>
</url>

πŸ”§ An Interesting Challenge

During the migration I ran into an unexpected issue. After removing the static sitemap.xmlfrom Angular SSR, requests were initially redirected to/sitemap.xml/home The fix was to configure Traefik so that every request for/sitemap.xmlis routed directly to the Spring Boot backend instead of the frontend.

Today https://redneckworks.bielski.nrw/sitemap.xml is served directly by the backend.

curl https://redneckworks.bielski.nrw/sitemap.xml

HTTP/2 200 OK Content-Type: application/xml;charset=UTF-8 Cache-Control: public, max-age=86400

It really works.


πŸ” Google Search Console

After deploying the new implementation, I simply resubmitted the existing sitemap in Google Search Console. From now on, every newly published article will automatically appear in the sitemap and can be discovered by Google during future crawls.No additional deployment is required.


βœ… Benefits of the New Architecture

  • πŸ›οΈ Clear separation of responsibilities

  • πŸš€ No frontend deployment for new content

  • ⚑ Always up-to-date XML sitemap

  • πŸ€– Better SEO automation

  • 🐳 Fewer Docker builds

  • πŸ“ˆ Much simpler publishing workflow


🎬 Related Video

Dynamic XML Sitemap with Spring Boot & Contentful

In this video, I explain why I moved XML sitemap generation from the Angular frontend into the Spring Boot backend.

You'll see:

  • the original architecture

  • why Angular was the wrong place for the sitemap

  • the complete Spring Boot implementation

  • deployment without rebuilding the frontend

  • verification in Google Search Console

  • how every new Contentful article is automatically added to the XML sitemap

Instead of discussing only the theory, I demonstrate the complete implementation, explain the architectural decisions behind it, and show the entire deployment process step by step.

Dynamic XML Sitemap with Spring Boot & Contentful

🎯 Final Thoughts

This was a relatively small technical change, but it significantly improved the overall architecture.Responsibilities are now clearly separated.

Component

Responsibility

πŸ“ Contentful

Content Management

β˜• Spring Boot

Business Logic, REST API & XML Sitemap

πŸ…°οΈ Angular SSR

User Interface Rendering

πŸ” Google

Crawl the Sitemap & Index Content

For me, this is a great example of how software architecture evolves over time. At the beginning of a project, many solutions seem perfectly reasonable. As the project grows, you start to recognize which component should actually own a specific responsibility.

In my case, the conclusion became obvious: