The XML Sitemap feature generates and serves a standards-compliant
sitemap.xmlfor any website published behind the Artica reverse-proxy, without touching the backend application.
Artica crawls the site directly on its backend servers, keeps only the canonical URLs that are really indexable, writes one or more Sitemap XML files, and serves them itself from the reverse-proxy.
The sitemap is regenerated on a schedule, announced inrobots.txt, and every decision the crawler took is visible in the console.The feature works per published website and is disabled by default.
It is available for reverse-proxy websites that forward to at least one backend server.
A sitemap is the list of URLs a site owner wants search engines to crawl and index.
Applications such as WordPress, PrestaShop or Magento generate their own from their database.
Static sites, in-house applications and legacy sites usually have none, and their administrators have no simple way to produce one.
Artica fills that gap from the one place that already sees every published site: the reverse-proxy.
How a generation works:
Host header. /page/2 or a noindex,follow page is followed but not published: utm_*, gclid and fbclid removed) and rel=canonical is honoured.Article, BlogPosting, Product…), then OpenGraph, then HTML structure. lastmod of each URL is taken from the most reliable source available, in this order: dateModified, article:modified_time, the HTTP Last-Modified header, a <time datetime> element, the date known from the previous crawl, and finally the date of the last successful scan of that URL. lastmod: search engines require this field to reflect an actual content change.pages, articles, products, images) under a sitemap.xml index. current link switched to the new generation. /sitemap.xml and the family files itself, from local disk. /sitemap.xml exactly as before.robots.txt, a Sitemap: noindex, robots.txt disallows, error pages, soft 404s, internal search results, pagination, duplicates and external canonicals are filtered out, so the sitemap does not send crawlers to pages that hurt the site's ranking.lastmod dates, 429 and 503 answers and never retries aggressively.noindex mistakes, redirect chains and duplicate content.Open Web services, select the website, and locate the XML Sitemap row in the site's parameters.
The row shows whether the feature is active and, when it is, the number of indexable URLs found by the last successful run.
Click the edit button to open the management window.

The management window has five tabs: Overview, Settings, URLs, Exclusions and History.
Open the Settings tab, switch Enable XML Sitemap on, adjust the parameters if needed and click Apply.

| Setting | Default | Range | Meaning |
|---|---|---|---|
| Enable XML Sitemap | Off | Activates the crawler, the scheduler and the reverse locations for this site. | |
| Override Existing Sitemap | Off | One-shot confirmation used when the backend already serves its own /sitemap.xml, or when Artica could not check it (see below). It is not stored. |
|
| Generation Interval (Hours) | 12 | 1 – 720 | Time between two scheduled generations, counted from the end of the last successful run. |
| Maximum Pages | 10 000 | 10 – 1 000 000 | Maximum number of pages fetched in one run. When reached, the run ends with the statussuccess_with_limits and the URLs that were discovered but never fetched are countedunder the crawl_limit reason. |
| Maximum Crawl Depth | 15 | 1 – 100 | Maximum number of links between the home page and a page. Deeper URLs are counted under crawl_depth. |
| Concurrency | 4 | 1 – 32 | Number of simultaneous requests sent to the backend. |
| Request Timeout (Seconds) | 15 | 2 – 120 | Timeout of each backend request. |
| Maximum Page Size (Bytes) | 8 388 608 | 262 144 – 33 554 432 | Pages larger than this are not parsed and are excluded with the body_too_large reason. |
| Respect Robots.Txt | On | Reads the site's robots.txt from the backend and excludes disallowed pathsfrom both the crawl and the sitemap ( robots_disallow). |
|
| Include Images | On | Collects the images of each published page and produces an image sitemap. | |
| Include Articles | On | Publishes the URLs classified as articles, in their own file. | |
| Include Products | On | Publishes the URLs classified as products, in their own file. | |
| Exclude Query Strings | Off | When on, any URL carrying a query string is excluded (query_string).Leave it off on sites that use parameters as legitimate page identifiers. |
Values outside the allowed range are refused with an explicit error, never silently clamped.
Enabling the feature triggers two checks before anything is written:
/sitemap.xml on the backend. 404 or anything that is not an XML sitemap: activation proceeds;/sitemap.xml is already served by a custom content file of the same site.After a successful activation, the first generation starts at the next scheduler tick (within a minute).
You can also start it immediately with Generate now in the Overview tab.
Disabling the feature removes the everse-proxy locations, so the backend receives /sitemap.xml again as before.
The generated files stay on disk for the history but are no longer served.
The Overview shows the state of the feature for this site and the result of the last successful run.

| Field | Meaning |
|---|---|
| State | Idle, or Running while a crawl is in progress for this site. |
| Last Run | Start time of the last successful run. Failed or interrupted runs are listed in the History tab but never shown here. |
| Indexable URLs / Excluded URLs | Number of distinct URLs of the last successful run that were published, and number that were excluded. Together they equal the size of the inventory shown in the URLs tab. |
| Pages Fetched | Number of HTTP requests actually sent to the backend during the run. |
| Errors | Number of URLs excluded because of a network error. |
| Next Run | Nominal date of the next scheduled generation (last successful run plus the interval). The real start is spread by up to 10 % to avoid all sites starting together. The field is absent until a first successful run exists. |
| Published URLs | Total number of entries in the published files. A page that carries images appears both in its family file and in the image sitemap, so this number can exceed the number of indexable URLs. |
| Top 5 exclusion reasons | The most frequent reasons of the last run. See the URLs tab for the full list. |
Generate now starts a manual run immediately.
The console then polls the daemon every three seconds and refreshes the tab when the run ends.
A second click while a run is in progress is refused (A generation is already running for this site), as is a manual run when the appliance-wide limit of two simultaneous crawls is reached.

The URLs tab is the inventory built by the crawler:
every URL discovered on the site, with its content type, HTTP status, verdict and, when excluded, the reason.
It is paginated on the server and can be filtered by path, verdict, content type, exclusion reason and HTTP status.

The exclusion reasons form a closed list:
| Reason | The URL was excluded because… |
|---|---|
noindex |
the page carries noindex in a robots or googlebot meta tag or in the X-Robots-Tag header. Its links are still followed unless nofollow is present. |
robots_disallow |
the path is disallowed by the site's robots.txt (when Respect Robots.Txt is on). |
non_200 |
the backend answered something other than 200 (404, 403, 5xx…). |
redirect_external |
the page redirects to a host that is not one of the site's host names. The redirection is not followed. |
canonical_external |
its rel=canonical points outside the site. |
duplicate |
another URL is the canonical form of the same content: explicit canonical, source of an internal redirection, or identical title, H1 and visible text. |
search |
it is an internal search results page. |
pagination |
it is a pagination page (/page/2, ?page=2…). It is followed, so that deep content is discovered, but not published. |
low_value |
it is a filter, sort, cart, checkout or similar variant with no indexing value. |
unsupported_content_type |
the response is not HTML (PDF, JSON, image, archive…). |
body_too_large |
the page exceeds Maximum Page Size. |
soft_404 |
the page answers 200 but is recognised as a "not found" page. |
query_string |
it carries a query string and Exclude Query Strings is on. |
custom_exclusion |
it matches one of the rules of the Exclusions tab. |
invalid_url |
the URL could not be parsed or normalised. |
network_error |
the backend request failed (timeout, connection error). |
crawl_depth |
it was discovered deeper than Maximum Crawl Depth and was never fetched. Counted in the run, but absent from the table since it has no inventory line. |
crawl_limit |
it was discovered after Maximum Pages was reached and was never fetched. Same remark as above. |
Weak heuristics never exclude a page on their own:
an article whose slug contains the word search is not treated as a search results page.
Detection combines the exact path, its segments, the query parameters and the HTML signals.
Exclusion rules let you keep URLs out of the sitemap even though the crawler would publish them:
a private area, a staging section, a family of parameters.
A rule only affects the publish verdict; the crawler still follows the links of an excluded page, so excluding a listing page does not hide what it links to.

Click Add exclusion to create a rule, or the pencil icon to edit one.

| Match type | Matches when… | Example |
|---|---|---|
exact |
the URL path is exactly the pattern. | /private-page excludes /private-page only, not /private-pages. |
prefix |
the URL path starts with the pattern. | /prive/ excludes the whole /prive/ tree. |
contains |
the URL path contains the pattern. | /preview excludes any path containing that word. |
query_param |
the URL carries a query parameter with that name. | sessionid excludes every URL with a sessionid= parameter. |
Rules are matched on the decoded path and parameters, never on the raw URL string.
A rule can be disabled without being deleted.
Rules take effect at the next run, scheduled or started with Generate now;
the excluded URLs then appear in the URLs tab with the custom_exclusion reason.
The History tab lists the last runs of this site, most recent first, with their trigger (manual or scheduled), status, counters, duration, and whether the run was published.

| Status | Meaning | Published |
|---|---|---|
success |
The crawl completed normally. | Yes |
success_with_limits |
The crawl completed but hit Maximum Pages, or met isolated timeouts or 5xx answers. The sitemap is published; review the crawl_limit and network_error counters. |
Yes |
failed |
The home page did not answer, no backend was reachable, the generated XML did not validate, or a file-system error occurred. |
No — the previous generation stays served |
interrupted |
The run was cancelled or the daemon was stopped while it was running. | No |
The last two generations are kept on disk; older ones are deleted after each successful publication.
The reverse-proxy serves the following URLs for the site, from local disk, with the security modules that could block a search engine crawler disabled on these paths:
/sitemap.xml — a sitemap index when several families or several files exist, otherwise a single URL set;/sitemap-pages-NNNN.xml, /sitemap-articles-NNNN.xml, /sitemap-products-NNNN.xml, /sitemap-images-NNNN.xml — the family files, numbered from 0001, split when a file would exceed the protocol limits.Example of the index generated for the site shown above:
<?xml version="1.0" encoding="UTF-8"?><sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> <sitemap><loc>http://sitemap-test.articatech.unix/sitemap-pages-0001.xml</loc><lastmod>2026-09-02T13:57:45Z</lastmod></sitemap> <sitemap><loc>http://sitemap-test.articatech.unix/sitemap-articles-0001.xml</loc><lastmod>2026-09-02T13:57:45Z</lastmod></sitemap> <sitemap><loc>http://sitemap-test.articatech.unix/sitemap-products-0001.xml</loc><lastmod>2026-09-02T13:57:45Z</lastmod></sitemap> <sitemap><loc>http://sitemap-test.articatech.unix/sitemap-images-0001.xml</loc><lastmod>2026-09-02T13:57:45Z</lastmod></sitemap></sitemapindex>
A family file, with the lastmod taken from the page content:
<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> <url><loc>http://sitemap-test.articatech.unix/</loc><lastmod>2026-08-25T08:00:00Z</lastmod></url> <url><loc>http://sitemap-test.articatech.unix/product-1</loc><lastmod>2026-09-02T15:52:48+02:00</lastmod></url></urlset>
In the image sitemap, the <loc> of each entry is the page, and its images are listed inside it, as the protocol requires:
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"> <url> <loc>http://sitemap-test.articatech.unix/product-1</loc> <image:image><image:loc>http://sitemap-test.articatech.unix/img/product-1.jpg</image:loc></image:image> </url></urlset>
When robots.txt is managed by Artica for this site, it ends with the announcement of the generated sitemap:
User-agent: *Disallow: /prive/Sitemap: http://sitemap-test.articatech.unix/sitemap.xml
URLs are built on the site's canonical host name and public scheme (HTTPS when the site has an SSL listener), never on the backend address.
robots.txt when asked to, limits concurrency per site,429 and 503 and honours Retry-After.interrupted in the History.
The feature is driven by the reverse-proxy daemon's REST API on the local Unix socket /run/reverse-proxy.sock. All routes are scoped by the website identifier.
| Route | Purpose |
|---|---|
GET /sitemap-xml/{serviceid}/settings |
The twelve settings as resolved for this site. |
POST /sitemap-xml/{serviceid}/settings |
Writes settings. Enabling probes the backend; the answer carries rebuild_ok and rebuild_error. Pass "force_replace": true (a JSON boolean) to override a conflict. |
POST /sitemap-xml/{serviceid}/generate |
Starts a manual run and returns its run_id immediately; 409 already_running or 503 no_slots_available otherwise. |
POST /sitemap-xml/{serviceid}/cancel |
Cooperative cancellation of the running crawl. |
GET /sitemap-xml/{serviceid}/status |
scheduler_running (the module started on this appliance), enabled (this site), running (a crawl is in flight), last successful run, next_run_at, published manifest. |
GET /sitemap-xml/{serviceid}/runs |
Run history, most recent first. |
GET /sitemap-xml/{serviceid}/runs/{runid} |
One run with its exclusion counters. |
GET /sitemap-xml/{serviceid}/urls |
Filterable, paginated inventory (q, indexable, content_type, reason, status, offset, limit up to 500). |
GET / POST /sitemap-xml/{serviceid}/exclusions |
List, create or update exclusion rules. |
POST /sitemap-xml/{serviceid}/exclusions/{id}/delete |
Removes a rule. |
Example from the appliance shell:
curl -s --unix-socket /run/reverse-proxy.sock http://x/sitemap-xml/90/statuscurl -s -X POST --unix-socket /run/reverse-proxy.sock http://x/sitemap-xml/90/generate
| Symptom | Cause and action |
|---|---|
| Activation refused: the backend already publishes its own sitemap.xml | The application serves a sitemap. Keep it if it is good; otherwise enable Override Existing Sitemap and apply again. |
| Activation refused: could not verify | The backend did not answer the probe within 10 seconds. Check the backend's health (Backend SLA, backend diagnostic) before overriding. |
| Activation refused: URI already served | /sitemap.xml is defined as a custom content file in the site's directories. Remove that entry first. |
| Enabled, but no run ever appears | Check scheduler_running in the status route: when the module could not open its database at daemon start, nothing is generated for any site. Restart the reverse-proxy daemon and check its log. |
Runs end in failed |
The home page did not answer 200 on the backend, or no backend was reachable. Test the backend from the appliance with the site's host name in the Host header. |
| Zero or very few indexable URLs | Look at the Top 5 exclusion reasons and filter the URLs tab by reason. Typical causes: a site-wide noindex on a staging backend, a robots.txt that disallows everything, every page redirecting to another host (redirect_external). |
success_with_limits on every run |
Raise Maximum Pages or Maximum Crawl Depth, or add exclusion rules for the parameter variants that inflate the crawl. |
/sitemap.xml returns 404 on the public site |
No generation has been published yet (first run still to come, or every run failed). The location exists but the file does not. |