Split product sitemap and use Farsi category URLs with ids.

sitemap.xml is now an index of main + products; category loc paths use /products/category/{id}/{nameFaSlug} with a public by-id lookup for storefronts.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-08-23 00:23:30 +03:30
co-authored by Cursor
parent c4367d8eb0
commit ea40ae40d8
13 changed files with 427 additions and 59 deletions
+95 -2
View File
@@ -195,7 +195,7 @@
"SEO"
],
"summary": "XML sitemap for search engines",
"description": "Published products, product categories, blogs, and portfolios for this tenant (respects enabled modules), plus static pages and URL templates from the synced website manifest (`GET https://{domain}/meshkee/sitemap-config.json`). Default detail paths: `/products/{id}/{nameFaSlug}`, `/products/category/{categorySlug}`, `/blog/{id}/{titleSlug}`, `/portfolios/{id}/{titleFaSlug}`. Proxied from `https://{domain}/sitemap.xml` on the storefront. Cached in Redis; refreshed after CMS writes and manifest sync.",
"description": "Sitemap **index** for this tenant. Points to `/sitemap-main.xml` (static pages, product categories, blogs, portfolios) and `/sitemap-products.xml` (published products when the products module is enabled). Category paths: `/products/category/{id}/{nameFaSlug}`. Product paths: `/products/{id}/{nameFaSlug}`. Proxied from `https://{domain}/sitemap.xml`. Cached in Redis; refreshed after CMS writes and manifest sync.",
"parameters": [
{
"$ref": "#/components/parameters/domain"
@@ -226,6 +226,56 @@
}
}
},
"/tenants/{domain}/sitemap-main.xml": {
"get": {
"tags": [
"SEO"
],
"summary": "Main sitemap urlset (static + categories + blogs + portfolios)",
"parameters": [
{
"$ref": "#/components/parameters/domain"
}
],
"responses": {
"200": {
"description": "Sitemap XML (urlset)",
"content": {
"application/xml": {
"schema": {
"type": "string"
}
}
}
}
}
}
},
"/tenants/{domain}/sitemap-products.xml": {
"get": {
"tags": [
"SEO"
],
"summary": "Products-only sitemap urlset",
"parameters": [
{
"$ref": "#/components/parameters/domain"
}
],
"responses": {
"200": {
"description": "Sitemap XML (urlset) of published products",
"content": {
"application/xml": {
"schema": {
"type": "string"
}
}
}
}
}
}
},
"/tenants/{domain}/robots.txt": {
"get": {
"tags": [
@@ -446,12 +496,55 @@
}
}
},
"/tenants/{domain}/categories/by-id/{categoryId}": {
"get": {
"tags": [
"Categories"
],
"summary": "Category by id (preferred for /products/category/{id}/{nameFaSlug} pages)",
"parameters": [
{
"$ref": "#/components/parameters/domain"
},
{
"name": "categoryId",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "entityType",
"in": "query",
"schema": {
"type": "string",
"enum": [
"product",
"blog",
"portfolio",
"video"
],
"default": "product"
}
}
],
"responses": {
"200": {
"description": "{ category } — use category.id as categoryId when listing products"
},
"404": {
"description": "Category not found"
}
}
}
},
"/tenants/{domain}/categories/by-slug/{slug}": {
"get": {
"tags": [
"Categories"
],
"summary": "Category by slug (for /products/category/{categorySlug} pages)",
"summary": "Category by CMS slug (legacy / lookup helper)",
"parameters": [
{
"$ref": "#/components/parameters/domain"