# Sitemaps easiest way

**URL:** <https://forum.getkirby.com/t/sitemaps-easiest-way/361>\
**Category:** Solutions\
**Tags:** v2\
**Created:** [March 9, 2015, 2:41pm UTC](https://forum.getkirby.com/t/sitemaps-easiest-way/361 "2015-03-09T14:41:22Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![PhoenixPeca](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/phoenixpeca/32/3409_2.png) [@PhoenixPeca](https://forum.getkirby.com/u/PhoenixPeca)\
**Post date:** [March 9, 2015, 2:41pm UTC](https://forum.getkirby.com/t/sitemaps-easiest-way/361/1 "2015-03-09T14:41:22Z")

</div>

Hello everyone,  
Let me present to you the easiest way to have sitemaps installed on your server. Its just a matter of copy and paste. To install; just download and paste the [sitemap.php](https://github.com/PhoenixPeca/Peca-Theme/blob/master/sitemap.php) file into the directory where you’ve installed kirby. Open the url of the sitemap.php in a browser.That’s it. This code is also open for recommendations. If you found an error pls dont hesitate to tell me. Thanks, and im happy to help you. Please take note that `sitemap.php` (without “s”) must be the name of the php file otherwise you’ll encounter problems, However, if you really wanted to rename it like `xmlsitemap.php` you should also edit the `sitemap.php` in line 16.  
A sincere message from the Philippines. 😉

---

<div class="post-metadata">

**Author:** ![FabianSperrle](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/fabiansperrle/32/5426_2.png) [@FabianSperrle](https://forum.getkirby.com/u/FabianSperrle)\
**Post date:** [March 9, 2015, 2:58pm UTC](https://forum.getkirby.com/t/sitemaps-easiest-way/361/2 "2015-03-09T14:58:51Z")

</div>

What are you using the regular expressions for? Is there an advantage over the version at [http://getkirby.com/blog/xmlsitemap](http://getkirby.com/blog/xmlsitemap)?

---

<div class="post-metadata">

**Author:** ![Luke](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/luke/32/3083_2.png) [@Luke](https://forum.getkirby.com/u/Luke)\
**Post date:** [March 9, 2015, 3:13pm UTC](https://forum.getkirby.com/t/sitemaps-easiest-way/361/3 "2015-03-09T15:13:42Z")

</div>

I include a “sitemap” field in all my blueprints and filter the xmlsitemap results that way. If you use a one page setup, or if you have pages that have children that act as content instead of another page (which I imagine nearly every kirby installation does), you’ll want more control over it.

For instance, if I had a slideshow on the home page, it’s content/home/slideshow/slide-1 , slide-2, slide-3. I don’t want to include the slide-1,2,3 directories… or even slideshow directory they reside in for that matter because they should never be accessed directly.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [March 9, 2015, 3:24pm UTC](https://forum.getkirby.com/t/sitemaps-easiest-way/361/4 "2015-03-09T15:24:19Z")

</div>

I think that’s actually the best way of doing it because otherwise you end up adding `not()` methods to your sitemap whenever you add new content or risk having stuff in your sitemap that you don’t want there at all …

---

<div class="post-metadata">

**Author:** ![anon77445132](https://avatars.discourse-cdn.com/v4/letter/a/4da419/32.png) [@anon77445132](https://forum.getkirby.com/u/anon77445132)\
**Post date:** [March 9, 2015, 5:43pm UTC](https://forum.getkirby.com/t/sitemaps-easiest-way/361/5 "2015-03-09T17:43:57Z")

</div>

> [@FabianSperrle](#):
>
> [http://getkirby.com/blog/xmlsitemap](http://getkirby.com/blog/xmlsitemap)

With the [KISS principle](http://en.wikipedia.org/wiki/KISS_principle) I say: “ **Keep it simple and straightforward** ”!

# Kirby 2.x:

## Installation

I added one line to the code [http://getkirby.com/blog/xmlsitemap](http://getkirby.com/blog/xmlsitemap) from @bastianallgeier in line 4, beginning with "$templateignore = ", and one line in line 16, beginning with “`<?php if(in_array($p->template(),`” and added “`->visible()`” in the `foreach` line, to get:

```php
<?php

$ignore = array('sitemap', 'error'); // pages with uri IN $ignore are ignored
$templateignore = array('internal', 'members' , 'member'); // pages with template IN $templateignore are ignored

// send the right header
header('Content-type: text/xml; charset="utf-8"');

// echo the doctype
echo '<?xml version="1.0" encoding="utf-8"?>';

?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <?php foreach($pages->index()->visible() as $p): ?>
  <?php if(in_array($p->uri(), $ignore)) continue ?>
  <?php if(in_array($p->template(), $templateignore)) continue ?>
  <url>
    <loc><?php echo html($p->url()) ?></loc>
    <lastmod><?php echo $p->modified('c') ?></lastmod>
    <priority><?php echo ($p->isHomePage()) ? 1 : number_format(0.5/$p->depth(), 1) ?></priority>
  </url>
  <?php endforeach ?>
</urlset>

```

Copy the entire code from above and put it in your `site/templates` directory in a new file called `xmlsitemap.php`

Go to your content folder and create a new invisible folder called `sitemap` and also add a text file to it called `xmlsitemap.txt`

Now we can exclude pages and templates.  
In my Kirby-websites, all **internal** (not public) webpages have a special template, which follows the instructions from [http://getkirby.com/docs/solutions/authentication](http://getkirby.com/docs/solutions/authentication) to protect the page from viewing by everybody. So we can exclude them very easy.

### Hint:

My new lines may be usefull in **public menus** too.

## Set up the routes

With @bastianallgeier at [https://github.com/getkirby/kirby/issues/93](https://github.com/getkirby/kirby/issues/93):

Open your file `site/config/config.php` and add the following lines, if there are no routes.  
If you find there one or some routes, only add the two nested `array`’s in front of your existing route(s).

```auto

/*
---------------------------------------
Setup Kirby Routes
---------------------------------------
*/
c::set('routes', array(
    /* https://github.com/getkirby/kirby/issues/93 */
    array(
        'pattern' => 'sitemap.xml',
        'action' => function() {
            return site()->visit('sitemap');
        }
    ),
    array(
        'pattern' => 'sitemap',
        'action' => function() {
            return go('sitemap.xml');
        }
    ),
));

```

## =\>

Good luck!

---

<div class="post-metadata">

**Author:** ![PhoenixPeca](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/phoenixpeca/32/3409_2.png) [@PhoenixPeca](https://forum.getkirby.com/u/PhoenixPeca)\
**Post date:** [March 10, 2015, 10:52am UTC](https://forum.getkirby.com/t/sitemaps-easiest-way/361/6 "2015-03-10T10:52:15Z")

</div>

Actually this method is the easiest method to install sitemap in kirby and that is the main advantage. Though I forget to put the most important line, the line that can allow you to exclude pages in the sitemap (I am really sorry for that, I’ll fix as soon as possible). Another thing, there are some replies I don’t understand, because im not that expert with kirby, Im just 14 and i still need to study.You are free to experiment with the codes and send me a pull request on github. Thank you. 🙂

---

<div class="post-metadata">

**Author:** ![PhoenixPeca](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/phoenixpeca/32/3409_2.png) [@PhoenixPeca](https://forum.getkirby.com/u/PhoenixPeca)\
**Post date:** [March 10, 2015, 11:28am UTC](https://forum.getkirby.com/t/sitemaps-easiest-way/361/7 "2015-03-10T11:28:56Z")

</div>

The functions are used to filter the url by removing the _file base name_ in the `<loc></loc>` tag. Without those functions you will end up having a url in the `loc` tag like this:  
[http://localhost/sitemap.php/parentpage/childpage/grandchildpage/](http://localhost/sitemap.php/parentpage/childpage/grandchildpage/)  
instead of this:  
[http://localhost/parentpage/childpage/grandchildpage/](http://localhost/parentpage/childpage/grandchildpage/)  
😄

---

<div class="post-metadata">

**Author:** ![jenstornell](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/jenstornell/32/546_2.png) [@jenstornell](https://forum.getkirby.com/u/jenstornell)\
**Post date:** [July 31, 2015, 2:01pm UTC](https://forum.getkirby.com/t/sitemaps-easiest-way/361/8 "2015-07-31T14:01:23Z")

</div>

An old thread now but I just tested it and I like how it looks for most part.

## Why sitemap as content page?

However I don’t like to create a content page just for it to show up on the site. We are not adding any content to it in the panel (in this example).

## Route it

I solved it, almost “by the book” but with one different thing. I load a template directly from the route. Then I don’t need to create content I don’t need.

```php
c::set('routes', array(
	array(
		'pattern' => 'sitemap.xml',
		'action' => function() {
			tpl::load(kirby()->roots()->templates() . DS . 'sitemap.php', array(), false );
		}
	),
	array(
		'pattern' => 'sitemap',
		'action' => function() {
			return go('sitemap.xml');
		}
	),
));

```

## Minor fix to the template

I use this template for it:

[http://getkirby.com/blog/xmlsitemap](http://getkirby.com/blog/xmlsitemap)

A minor problem is that $page is unknown because the template is called directly from the route. It’s easily fixed by adding this row on line 2.

```php
$pages = site()->pages();

```

---

<div class="post-metadata">

**Author:** ![jenstornell](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/jenstornell/32/546_2.png) [@jenstornell](https://forum.getkirby.com/u/jenstornell)\
**Post date:** [August 1, 2015, 8:27pm UTC](https://forum.getkirby.com/t/sitemaps-easiest-way/361/9 "2015-08-01T20:27:40Z")

</div>

## An even shorter version

Put this in your `templates/sitemap.php` like before:  
[http://getkirby.com/blog/xmlsitemap](http://getkirby.com/blog/xmlsitemap)

### The route

```php
c::set('routes', array(
	array(
		'pattern' => 'sitemap.xml',
		'action' => function() {
			tpl::load(kirby()->roots()->templates() . DS . 'sitemap.php', array( 'pages' => site()->pages() ), false );
		}
	),
));

```

That’s it.

- Now you don’t have to modify the template in any way.
- There is no need to redirect `/sitemap` because we don’t use the content method.

## As a plugin

In case you want it as a plugin, just save the above code in `/site/plugins/sitemap/sitemap.php` and change the first row to this:

```php
kirby()->routes( array(

```

---

<div class="post-metadata">

**Author:** ![flokosiol](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/flokosiol/32/468_2.png) [@flokosiol](https://forum.getkirby.com/u/flokosiol)\
**Post date:** [August 5, 2015, 11:51am UTC](https://forum.getkirby.com/t/sitemaps-easiest-way/361/10 "2015-08-05T11:51:16Z")

</div>

Thanks for sharing. This was very helpful!

[Edit: I was looking for a way to load a template file for a custom route, and this did the trick]

---

<div class="post-metadata">

**Author:** ![JanStieler](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/janstieler/32/15642_2.png) [@JanStieler](https://forum.getkirby.com/u/JanStieler)\
**Post date:** [August 8, 2015, 4:30pm UTC](https://forum.getkirby.com/t/sitemaps-easiest-way/361/11 "2015-08-08T16:30:09Z")

</div>

HI,  
there is also a plugin listet in the [Plugins & Extensions Site](http://getkirby-plugins.com/xml-sitemap-generator)

---

<div class="post-metadata">

**Author:** ![nerdmed](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/nerdmed/32/3408_2.png) [@nerdmed](https://forum.getkirby.com/u/nerdmed)\
**Post date:** [December 18, 2016, 4:44pm UTC](https://forum.getkirby.com/t/sitemaps-easiest-way/361/12 "2016-12-18T16:44:27Z")

</div>

hey guys i have tried all the above. In my installation it works for the route `/sitemap` but does not work for the `.xml` extension. I tried to redirect the page but it does not even seem to get this far. My redirects are working for normal page but not as soon as i add an extension to the url. Any ideas what the reason could be? Maybe its something inside the default .htaccess ?

EDIT: Found out that this problem only exists when working locally on a server it works fine. So ensure to try it online before wasting your time. Although it would be interesting to know the reason.

---

<div class="post-metadata">

**Author:** ![anon77445132](https://avatars.discourse-cdn.com/v4/letter/a/4da419/32.png) [@anon77445132](https://forum.getkirby.com/u/anon77445132)\
**Post date:** [December 18, 2016, 9:26pm UTC](https://forum.getkirby.com/t/sitemaps-easiest-way/361/13 "2016-12-18T21:26:47Z")

</div>

@nerdmed:  
Hint:  
I don’t know, but I think, you don’t have ONLY one line starting with

> [@jenstornell](#):
>
> c::set(‘routes’, array(

in your file `site/config/config.php`. You need only ONE line of this, not none or more!

And that would be your problem I think.

Good luck!

---

<div class="post-metadata">

**Author:** ![nerdmed](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/nerdmed/32/3408_2.png) [@nerdmed](https://forum.getkirby.com/u/nerdmed)\
**Post date:** [December 20, 2016, 1:10am UTC](https://forum.getkirby.com/t/sitemaps-easiest-way/361/14 "2016-12-20T01:10:03Z")

</div>

hey @anon77445132 thanks for your reply. Actually I am aware that there only can be one routes array. It still works on my production server but not on localhost.

---

<div class="post-metadata">

**Author:** ![anon77445132](https://avatars.discourse-cdn.com/v4/letter/a/4da419/32.png) [@anon77445132](https://forum.getkirby.com/u/anon77445132)\
**Post date:** [December 21, 2016, 6:35pm UTC](https://forum.getkirby.com/t/sitemaps-easiest-way/361/15 "2016-12-21T18:35:03Z")

</div>

@nerdmed:  
Look whether you have more than one `config*.php` file on your localhost webserver like `config.127.0.0.1.php` or `config.localhost.php`.

For details look at [Docs: **Multi-environment setup**](https://getkirby.com/docs/developer-guide/configuration/options).

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [December 21, 2016, 10:04pm UTC](https://forum.getkirby.com/t/sitemaps-easiest-way/361/16 "2016-12-21T22:04:34Z")

</div>

What is your current setup?

---

<div class="post-metadata">

**Author:** ![distantnative](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/distantnative/32/11319_2.png) [@distantnative](https://forum.getkirby.com/u/distantnative)\
**Post date:** [February 6, 2025, 4:53pm UTC](https://forum.getkirby.com/t/sitemaps-easiest-way/361/17 "2025-02-06T16:53:07Z")

</div>


