Sitemaps
Sitemaps is a flexible, fast Elixir library for generating standard XML and gzip-compressed (.xml.gz) sitemaps and sitemap index files compliant with search engine specifications (Google, Bing, etc.).
Origin & Attribution: This library is an actively maintained fork and evolution of the original
sitemappackage created by Tatsuo Ikeda (ikeikeikeike). It was modernized for current Elixir and Erlang/OTP releases, featuring strict test coverage (95%+), improved documentation, type specifications, and updated dependencies.
Features
- Standard & Gzip Sitemaps: Generates uncompressed
.xmlor gzip-compressed.xml.gzfiles out of the box. - Automatic Index & Segmentation: Seamlessly rotates files and builds a
<sitemapindex>when exceeding link count (default 10,000, up to 50,000) or file size limits (50 MB). - Clean Macro DSL: Intuitive
create,add, andadd_to_indexmacros for structuring your sitemaps. - Comprehensive Metadata Extensions:
- Images: Captions, titles, geo-location, and license information.
- Videos: Thumbnails, titles, descriptions, player locations, duration, ratings, tags, and family-friendly flags.
- News: Publication names, languages, publication dates, titles, genres, keywords, and stock tickers.
- Alternate Languages: Localized URL alternates (
hreflang) viaxhtml:link. - Mobile: Mobile search engine tags (
<mobile:mobile/>). - PageMap: Google structured data attributes.
- Search Engine Pings: Built-in automatic ping notifications for Google and Bing (
Sitemaps.Generator.ping/1orping/1). - Flexible Configuration: Configure globally via
config.exs, system environment variables, or per-sitemap options.
Installation
Add sitemaps to your list of dependencies in mix.exs:
def deps do
[
{:sitemaps, "~> 0.1"}
]
end
Quick Start
Basic Usage
defmodule MyApp.Sitemaps do
use Sitemaps
def generate do
create do
add "/", priority: 1.0, changefreq: "daily"
add "/about", priority: 0.8, changefreq: "weekly"
add "/contact", priority: 0.5, changefreq: "monthly"
end
# Notify search engines (Google and Bing) of the updated sitemap
ping()
end
end
With Phoenix (Verified Routes)
defmodule MyAppWeb.Schedulers.Sitemaps do
use Sitemaps
use Phoenix.VerifiedRoutes,
endpoint: MyAppWeb.Endpoint,
router: MyAppWeb.Router
def generate do
Sitemaps.Config.set(:files_path, "#{:code.priv_dir(:my_app_web)}/static/sitemaps/")
Sitemaps.Config.set(:host, "https://example.com")
create do
add ~p"/", priority: 1.0, changefreq: "daily"
add ~p"/about", priority: 0.8, changefreq: "weekly"
for post <- MyApp.Blog.list_posts() do
add ~p"/blog/#{post.slug}",
priority: 0.7,
changefreq: "monthly",
lastmod: post.updated_at
end
end
ping()
end
end
Rich Metadata Examples
Images
add "/gallery",
images: [
[loc: "https://example.com/photo1.jpg", title: "Sunset", caption: "Beach sunset", geo_location: "Malaga, Spain"],
[loc: "https://example.com/photo2.jpg", title: "Mountains", license: "https://creativecommons.org/licenses/by/4.0/"]
]
Videos
add "/videos/elixir-intro",
videos: [
[
thumbnail_loc: "https://example.com/thumb.jpg",
title: "Introduction to Elixir",
description: "Learn concurrent programming with Elixir and OTP",
content_loc: "https://example.com/video.mp4",
player_loc: "https://example.com/player?id=123",
duration: 600,
family_friendly: true,
tag: ["elixir", "erlang", "otp"]
]
]
News
add "/news/release-announcement",
news: [
publication: [name: "Tech Times", language: "en"],
publication_date: ~D[2026-09-02],
title: "New Elixir Release Out Now",
genres: "PressRelease",
keywords: ["elixir", "programming", "technology"]
]
Alternate Languages (hreflang)
add "/products/book",
alternates: [
[href: "https://example.com/en/products/book", lang: "en"],
[href: "https://example.com/es/products/book", lang: "es"]
]
Mobile & PageMap
add "/mobile-page", mobile: true
add "/structured-page",
pagemap: [
dataobjects: [
[
type: "document",
id: "doc-1",
attributes: [
[name: "title", value: "Custom Title"],
[name: "rating", value: "4.8"]
]
]
]
]
Configuration
You can configure options in config/config.exs, passing them to use Sitemaps, or at runtime:
config :sitemaps,
host: "https://example.com",
files_path: "priv/static/sitemaps/",
public_path: "sitemaps/",
compress: true,
max_sitemap_links: 10_000
Available Options
| Option | Environment Variable | Default | Description |
|---|---|---|---|
:host |
SITEMAPS_HOST |
"http://www.example.com" |
Base URL scheme and host for generated links |
:files_path |
SITEMAPS_SITEMAPS_PATH |
"sitemaps/" |
Filesystem path where sitemap files are written |
:public_path |
SITEMAPS_PUBLIC_PATH |
"sitemaps/" |
URL path where sitemaps are served from |
:filename |
SITEMAPS_FILENAME |
"sitemap" |
Base filename for the sitemaps |
:compress |
SITEMAPS_COMPRESS |
true |
When true, compresses files with gzip (.xml.gz) |
:max_sitemap_links |
SITEMAPS_MAXLINKS |
10_000 |
Maximum number of URLs per sitemap file (max 50,000) |
:max_sitemap_files |
SITEMAPS_MAXFILES |
10_000 |
Maximum sitemaps per index file |
:max_sitemap_file_size |
SITEMAPS_MAXFILESIZE |
5_000_000 |
Maximum uncompressed byte size per file |
:create_index |
SITEMAPS_CREATE_INDEX |
"auto" |
"auto", true, or false for index creation |
:verbose |
SITEMAPS_VERBOSE |
true |
Enable or disable informational console logs |
Acknowledgements & Credits
- Original creator and maintainer: Tatsuo Ikeda (
ikeikeikeike). - Inspired by:
- sitemap_generator (Ruby)
- go-sitemap-generator (Go)
License
This project is licensed under the MIT License.