Sitemap.xml in CakePHP 5 with incorrect http header content-type

Hello folks.
I followed the manual description for XML Views to generate a sitemap.xml

But I get an wrong content-type error:
Incorrect http header content-type: “text/html; charset=UTF-8” (expected: “application/xml”)

This is my Controller:

<?php
declare(strict_types=1);

namespace App\Controller;

use Cake\Routing\Router;
use Cake\View\XmlView;
use Cake\I18n\DateTime;

/**
 * Sitemap Controller
 */
class SitemapController extends AppController
{
    /**
     * @param \Cake\Event\EventInterface $event
     * @return \Cake\Http\Response|void|null
     */
    public function beforeFilter(\Cake\Event\EventInterface $event)
    {
        parent::beforeFilter($event);
        $this->Authentication->addUnauthenticatedActions(['sitemap']);
    }

    public function viewClasses(): array
    {
        return [XmlView::class];
    }

    /**
     * Provides a sitemap as an XML document, following the sitemap protocol.
     *
     * @link https://www.sitemaps.org/protocol.html
     */
    public function sitemap()
    {
        $pages = $this->fetchTable('Pages')->find('all', fields: ['id', 'slug', 'modified'], order: ['pages_order' => 'ASC']);
            foreach ($pages as $entry) {
                $urls[] = [
                    'loc' => Router::url(['controller' => 'Pages', 'action' => 'view', 'id' => $entry->id, 'slug' => $entry->slug, '_full' => true]),
                    'lastmod' => $entry->modified->format('Y-m-d'),
                    'changefreq' => 'weekly',
                    'priority' => '0.5',
                ];
            }

        // Define a custom root node in the generated document.
        $this->viewBuilder()
            ->setOption('rootNode', 'urlset')
            ->setOption('serialize', ['@xmlns', 'url']);
        $this->set([
            // Define an attribute on the root node.
            '@xmlns' => 'http://www.sitemaps.org/schemas/sitemap/0.9',
            'url' => $urls,
        ]);
    }
}

What am I missing?

I couldn’t reproduce the incorrect Content-Type using your code but you might try this to override the current incorrect setting.

  $this->response = $this->getResponse()->withType('xml');

Thanks! I added your suggestion, but still get the Error:
Incorrect http header content-type: “text/html; charset=UTF-8” (expected: “application/xml”)

I validate here:

Also check your routing it doesn’t appear to be sending back the sitemap XML but a HTML page.

   # config/routes.php

    use Cake\Routing\RouteBuilder;
    use Cake\Routing\Router;

    Router::scope('/', function (RouteBuilder $routes) {
        // Other routes...

        $routes->connect('/sitemap.xml', ['controller' => 'Sitemap', 'action' => 'sitemap']);
    });

1 Like

That’s the solution:

<?php
use Cake\Routing\Route\DashedRoute;
use Cake\Routing\RouteBuilder;


return function (RouteBuilder $routes): void {

    $routes->setRouteClass(DashedRoute::class);

    $routes->scope('/', function (RouteBuilder $builder): void {

        $builder->connect('/sitemap', ['controller' => 'Sitemap', 'action' => 'sitemap'])->setExtensions(['xml']);
...

Thank you! :slight_smile: