Skip to content

Commit 551f7a3

Browse files
authored
(feat) Add /sitemap.xml for crawlers (#29)
* (feat) Add /sitemap.xml - generated on demand * Bump version 1.2.3
1 parent 617d7ef commit 551f7a3

4 files changed

Lines changed: 80 additions & 1 deletion

File tree

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
defmodule RevstackWeb.SitemapController do
2+
use RevstackWeb, :controller
3+
4+
@paths [
5+
"/",
6+
"/about",
7+
"/services",
8+
"/estimate",
9+
"/contact",
10+
"/privacy",
11+
"/thanks",
12+
"/whoami",
13+
"/resume/kyle-neal-resume.pdf",
14+
"/resume/download/kyle-neal-resume.pdf"
15+
]
16+
17+
def index(conn, _params) do
18+
body =
19+
[
20+
~s(<?xml version="1.0" encoding="UTF-8"?>),
21+
~s(<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">),
22+
Enum.map_join(@paths, "", &url_entry/1),
23+
"</urlset>"
24+
]
25+
|> IO.iodata_to_binary()
26+
27+
conn
28+
|> put_resp_header("content-type", "application/xml; charset=utf-8")
29+
|> send_resp(:ok, body)
30+
end
31+
32+
defp url_entry(path) do
33+
"<url><loc>#{absolute_url(path)}</loc></url>"
34+
end
35+
36+
defp absolute_url(path) do
37+
RevstackWeb.Endpoint.url()
38+
|> URI.new!()
39+
|> URI.merge(path)
40+
|> to_string()
41+
end
42+
end

lib/revstack_web/router.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ defmodule RevstackWeb.Router do
2626
scope "/", RevstackWeb do
2727
pipe_through :browser
2828

29+
get "/sitemap.xml", SitemapController, :index
2930
get "/resume/kyle-neal-resume.pdf", ResumeController, :view
3031
get "/resume/download/kyle-neal-resume.pdf", ResumeController, :download
3132

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ defmodule Revstack.MixProject do
44
def project do
55
[
66
app: :revstack,
7-
version: "1.2.2",
7+
version: "1.2.3",
88
elixir: "~> 1.15",
99
elixirc_paths: elixirc_paths(Mix.env()),
1010
start_permanent: Mix.env() == :prod,
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
defmodule RevstackWeb.SitemapControllerTest do
2+
use RevstackWeb.ConnCase, async: true
3+
4+
describe "GET /sitemap.xml" do
5+
test "returns an XML sitemap for public routes", %{conn: conn} do
6+
conn = get(conn, "/sitemap.xml")
7+
base_url = RevstackWeb.Endpoint.url()
8+
9+
assert conn.status == 200
10+
assert ["application/xml; charset=utf-8"] == get_resp_header(conn, "content-type")
11+
assert conn.resp_body =~ ~s(<?xml version="1.0" encoding="UTF-8"?>)
12+
assert conn.resp_body =~ ~s(<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">)
13+
14+
for path <- [
15+
"/",
16+
"/about",
17+
"/services",
18+
"/estimate",
19+
"/contact",
20+
"/privacy",
21+
"/thanks",
22+
"/whoami",
23+
"/resume/kyle-neal-resume.pdf",
24+
"/resume/download/kyle-neal-resume.pdf"
25+
] do
26+
assert conn.resp_body =~ "<loc>#{base_url}#{path}</loc>"
27+
end
28+
end
29+
30+
test "does not render a 404 response", %{conn: conn} do
31+
conn = get(conn, "/sitemap.xml")
32+
33+
refute conn.resp_body == "Not Found"
34+
end
35+
end
36+
end

0 commit comments

Comments
 (0)