Recently, I shipped a Parts Finder feature in Odoo v19 that generated 30,000+ pages dynamically. As you might expect, the real challenge was not page generation—it was making sure search engines could actually discover and index those pages efficiently.
This article walks through how I designed the architecture, implemented dynamic sitemaps in Odoo, and handled SEO at scale without performance bottlenecks.
The Problem — SEO at Scale in Odoo
When your application creates tens of thousands of URLs dynamically, relying on static sitemap files is not an option. We needed a solution that:
- Automatically reflects new data
- Scales beyond 30,000 URLs
- Works cleanly with Odoo’s routing system
- Plays well with Google Search Console
Odoo’s built-in sitemap generator turned out to be the right tool—if used correctly.
URL Architecture for the Parts Finder
Before touching sitemaps, I finalized a logical and crawlable URL structure. Each level narrows the context, making URLs both user-friendly and SEO-friendly.
The Parts Finder starts with a high-level equipment type selection, designed to keep both users and search engines on a clean, hierarchical path.
URL Hierarchy
/type
/type/{type}
/type/{type}/brand/{id}
/type/{type}/brand/{id}/model/{id}
Type-to-Brand Navigation Layer
Once a user selects an equipment type, the system dynamically lists available manufacturers based on actual data relationships.
How Each Level Is Filtered
Types: Derived from selection field values in
tractor.modelBrands:
Many2onerelationship tied to equipment typeModels: Filtered by both type and brand
Parts: Linked via
Many2manythroughpart.fitment.spec
This structure ensured clean internal linking and predictable crawl paths for search engines.
Implementing Dynamic Sitemaps in Odoo v19
Odoo generates sitemaps using generator functions attached to routes. Instead of manually listing URLs, we let the database drive sitemap creation.
Sitemap Generator Example
Below is a real-world snapshot of how multiple sitemap generators were structured inside the Odoo controller.
@staticmethod
def sitemap_models(env, rule, qs):
Model = env['tractor.model']
for rec in Model.sudo().search([
('brand_id', '!=', False),
('tractor_type', '!=', False)
]):
loc = '/type/%s/brand/%s/model/%s' % (
rec.tractor_type,
rec.brand_id.id,
rec.id
)
if not qs or qs.lower() in loc:
yield {'loc': loc}
@http.route('/type/.../model/',
sitemap=sitemap_models)
def model_page(self, ...):
...
Each model page is a fully indexable endpoint, dynamically populated with compatible parts and fitment data.
Why This Works Well
The generator yields dictionaries with a
lockeyThe
qsparameter allows query-based filtering, which is essential for large sitemapsOdoo automatically splits sitemaps once URLs exceed ~45,000
Generated sitemaps are cached as
ir.attachment, improving performance
Operational Notes and Caching Behavior
One important thing to remember: sitemap files are cached. If your underlying data changes, you must clear the sitemap cache; otherwise, search engines will keep seeing outdated URLs.
This caching behavior is great for performance, but it requires discipline during deployments and data updates.
Lessons Learned from Real-World Usage
After implementing and monitoring the sitemap in production, a few best practices became very clear:
Always use
@staticmethod
Sitemap generators run outside the normal request lifecycle.Always call
.sudo()
Sitemap generation requires unrestricted read access.Avoid naming variables
page
This conflicts withwebsite.layoutand can cause subtle bugs.Test locally and objectively
A simple command works wonders:
curl localhost:8069/sitemap.xml | grep -c ""
Results and Indexing Performance
Before implementation, the sitemap contained zero URLs. After deployment, it jumped to 30,000+ URLs.
The most encouraging result:
Google Search Console began indexing the pages within 48 hours.
That alone validated the approach.
Final Thoughts
Odoo’s sitemap system is extremely powerful, but it’s also under-documented. With the right architecture and generator logic, you can handle SEO at serious scale without external tools or custom cron jobs.
If you’re building a large-scale Odoo website and need expert guidance, book a discovery call to plan the implementation.
For more insights on scaling SEO and performance in Odoo, explore my blog for practical strategies on building high-performing, search-friendly Odoo websites.