This guide assumes you’ve completed the Storefront tutorial. You should have working brand pages.
SEO-Friendly URLs
Rather than using database IDs in URLs:Step 1: Add SEO Columns
Add columns for slug and meta fields:slug- SEO-friendly URL with unique indexmeta_title- Custom page title for search enginesmeta_description- Description shown in search results
Step 2: Add FriendlyId to the Model
Add FriendlyId to generate SEO-friendly URLs automatically:app/models/spree/brand.rb
slug_candidates method is already defined in Spree::Base:
Step 3: Add SEO Fields to Admin
Spree provides a reusable SEO partial that handles slug, meta title, and meta description with a live search preview. Update your admin form:app/views/spree/admin/brands/_form.html.erb
- Live preview of how the page will appear in search results
- Meta title field with character count
- Meta description field
- Slug field with auto-generation from name
seo-form Stimulus controller syncs the preview with your form inputs in real-time.
Don’t forget to permit the SEO attributes in your controller:
app/controllers/spree/admin/brands_controller.rb
Step 4: Use Slugs in Storefront
Update your controller to usefriendly.find:
app/controllers/spree/brands_controller.rb
friendly.find method:
- Finds by slug first (e.g.,
/brands/nike-sportswear) - Falls back to ID if no slug matches
- Raises
ActiveRecord::RecordNotFoundif neither is found
URL Helpers
Always pass the model object to path helpers:to_param to return the slug automatically.
Handling Slug Changes
To redirect old URLs when slugs change, enable slug history:app/models/spree/brand.rb
Meta Tags & Open Graph
Spree automatically generates meta tags and Open Graph data. The system uses a helper calledobject that finds the main instance variable based on your controller name.
For BrandsController, Spree looks for @brand and generates:
- Meta description
- Open Graph tags (og:title, og:description, og:image)
- Twitter Card tags
Page Title
Overrideaccurate_title in your controller to set the page <title>:
app/controllers/spree/brands_controller.rb
Meta Description
Spree checks these sources in order:@page_descriptioninstance variable (if set)@brand.meta_description(if the model has this attribute)current_store.meta_description(fallback)
Using the SEO Partial
If you followed Step 1 and Step 3, your model already hasmeta_description and the admin form uses the SEO partial. Spree will automatically use @brand.meta_description for the page description.
Manual Override
For custom logic, set@page_description directly:
Social Sharing Image
For Open Graph images, Spree checks:@page_imageinstance variable (if set)@brand.image(if the model responds toimage)current_store.social_image(fallback)
logo but not image, add an alias:
app/models/spree/brand.rb
Complete SEO-Optimized Model
Here’s a complete Brand model with full SEO support:app/models/spree/brand.rb
Complete SEO-Optimized Controller
app/controllers/spree/brands_controller.rb
SEO Checklist
Friendly URLs - Use slugs instead of IDs (
/brands/nike not /brands/1)Page Titles - Override
accurate_title for descriptive titlesMeta Descriptions - Add
meta_description field or set @page_descriptionSocial Images - Provide
image method or set @page_image for Open GraphSlug History - Enable FriendlyId history to handle URL changes gracefully
Related Documentation
- Storefront Tutorial - Building storefront pages
- Model Tutorial - Creating the Brand model
- Admin Tutorial - Building the admin interface

