Simple Sitemap in Phoenix Elixir
For this website, we built a sitemap with Phoenix. I wanted to share what we did to make this happen.
Keep in mind, this is really simple and probably the easiest way to get a sitemap up and running. If your site has a ton of pages, I would recommend trying to cache this file as it can get quite large.
If you have done the example tutorial in the Phoenix guides, you should be able to follow this guide exactly.
Let's get started:
First off, let’s add to lib/hello_web/router.ex
a new pipeline.
pipeline :xml do
plug :accepts, ["xml"]
plug :put_layout, {HelloWeb.LayoutView, :none}
plug :put_resp_content_type, "application/xml"
end
Looking at this pipeline, we noticed a few things. The line plug :accepts, ["xml"]
tells us to only accept requests for XML. We select :none
as our layout since the whole page will be defined in our template. We also set our response content type to application/xml
. This tells the page to respond with XML.
Now let’s add to our router the path:
scope "sitemap", HelloWeb do
pipe_through :xml
get "/", SitemapController, :index
end
We are using the pipeline we created earlier and defining the path to the sitemap controller.
Next, we need to create the controller for our sitemap. It looks like this:
defmodule HelloWeb.SitemapController do
use HelloWeb, :controller
alias Hello.CMS
def index(conn, _params) do
pages = CMS.list_pages()
render(conn, "index.xml", pages: pages)
end
end
We first fetch all the pages using our CMS context and then render index.xml with all the pages set as assigns.
We need to also make a view for our sitemap:
defmodule HelloWeb.SitemapView do
use HelloWeb, :view
end
For this simple example, we don’t need to add anything to our view.
Lastly, we need to add our /lib/hello_web/templates/sitemap/index.xml.eex
:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<%= for page <- @pages do %>
<url>
<loc><%= page_url(@conn, :show, page) %></loc>
</url>
<% end %>
</urlset>