Overview
Search Engine Optimization (SEO) in OpenCart helps your store rank better in search results and provides user-friendly URLs. The system includes SEO URL management, regex-based URL patterns, and per-entity meta tag configuration.
SEO URL System
URL Structure
OpenCart converts dynamic URLs into clean, search-engine-friendly URLs:
index.php?route=product/product&product_id=42
index.php?route=product/category&path=20_27
index.php?route=information/information&information_id=4
macbook-pro-13-inch
laptops/macbooks
about-us
Database Structure
-- SEO URL mappings
CREATE TABLE `oc_seo_url` (
`seo_url_id` int NOT NULL AUTO_INCREMENT,
`store_id` int NOT NULL,
`language_id` int NOT NULL,
`key` varchar(64) NOT NULL,
`value` varchar(255) NOT NULL,
`keyword` varchar(255) NOT NULL,
`sort_order` int NOT NULL DEFAULT '0',
PRIMARY KEY (`seo_url_id`),
KEY `keyword` (`keyword`),
KEY `key_value` (`key`,`value`)
);
-- SEO regex patterns
CREATE TABLE `oc_seo_regex` (
`seo_regex_id` int NOT NULL AUTO_INCREMENT,
`key` varchar(64) NOT NULL,
`match` varchar(255) NOT NULL,
`replace` varchar(255) NOT NULL,
`keyword` varchar(255) NOT NULL,
`value` varchar(255) NOT NULL,
`sort_order` int NOT NULL DEFAULT '0',
PRIMARY KEY (`seo_regex_id`)
);
Managing SEO URLs
Access SEO URL Manager
Navigate to Design → SEO URLs in your admin panel.
Add New SEO URL
Click Add New to create a URL mapping:$seo_url_data = [
'store_id' => 0,
'language_id' => 1,
'key' => 'product_id',
'value' => '42',
'keyword' => 'macbook-pro-13',
'sort_order' => 0
];
Configure URL Components
- Key: Entity type (product_id, category_id, information_id)
- Value: Entity ID
- Keyword: SEO-friendly URL slug
- Store: Select store (multi-store support)
- Language: Select language
SEO URL Controller
namespace Opencart\Admin\Controller\Design;
class SeoUrl extends \Opencart\System\Engine\Controller {
public function save(): void {
$this->load->language('design/seo_url');
$this->load->model('design/seo_url');
$json = [];
$required = [
'seo_url_id' => 0,
'store_id' => 0,
'language_id' => 0,
'key' => '',
'value' => '',
'keyword' => ''
];
$post_info = $this->request->post + $required;
// Validate key length
if (!oc_validate_length($post_info['key'], 1, 64)) {
$json['error']['key'] = 'Key must be 1-64 characters';
}
// Validate value length
if (!oc_validate_length($post_info['value'], 1, 255)) {
$json['error']['value'] = 'Value must be 1-255 characters';
}
// Check for duplicate key/value pair
$seo_url_info = $this->model_design_seo_url->getSeoUrlByKeyValue(
$post_info['key'],
$post_info['value'],
$post_info['store_id'],
$post_info['language_id']
);
if ($seo_url_info &&
(!$post_info['seo_url_id'] ||
$seo_url_info['seo_url_id'] != $post_info['seo_url_id'])) {
$json['error']['value'] = 'This key/value pair already exists';
}
// Validate keywords
$keywords = explode('/', $post_info['keyword']);
foreach ($keywords as $keyword) {
if (!oc_validate_length($keyword, 1, 64)) {
$json['error']['keyword'] = 'Each keyword must be 1-64 characters';
}
if (!oc_validate_path($keyword)) {
$json['error']['keyword'] = 'Keyword contains invalid characters';
}
}
// Check for duplicate keyword
$seo_url_info = $this->model_design_seo_url->getSeoUrlByKeyword(
$post_info['keyword'],
$post_info['store_id']
);
if ($seo_url_info &&
(($seo_url_info['key'] != $post_info['key']) ||
($seo_url_info['value'] != $post_info['value']))) {
$json['error']['keyword'] = 'Keyword already in use';
}
if (!$json) {
if (!$post_info['seo_url_id']) {
$json['seo_url_id'] = $this->model_design_seo_url->addSeoUrl(
$post_info['key'],
$post_info['value'],
$post_info['keyword'],
$post_info['store_id'],
$post_info['language_id'],
(int)$post_info['sort_order']
);
} else {
$this->model_design_seo_url->editSeoUrl(
$post_info['seo_url_id'],
$post_info['key'],
$post_info['value'],
$post_info['keyword'],
$post_info['store_id'],
$post_info['language_id'],
(int)$post_info['sort_order']
);
}
$json['success'] = 'SEO URL saved successfully';
}
}
}
Common SEO URL Patterns
Products
// Product URLs
[
'key' => 'product_id',
'value' => '42',
'keyword' => 'macbook-pro-13-inch'
]
// Result: /macbook-pro-13-inch
Categories
// Category URLs (hierarchical)
[
'key' => 'path',
'value' => '20',
'keyword' => 'laptops'
],
[
'key' => 'path',
'value' => '20_27',
'keyword' => 'laptops/macbooks'
]
// Result: /laptops/macbooks
Information Pages
// Static pages
[
'key' => 'information_id',
'value' => '4',
'keyword' => 'about-us'
]
// Result: /about-us
Manufacturers
// Manufacturer pages
[
'key' => 'manufacturer_id',
'value' => '8',
'keyword' => 'apple'
]
// Result: /apple
SEO Regex Patterns
For dynamic URL generation, use regex patterns:
Accessing SEO Regex
Go to Design → SEO Regex to create pattern-based rules.
Regex Controller
namespace Opencart\Admin\Controller\Design;
class SeoRegex extends \Opencart\System\Engine\Controller {
public function save(): void {
$this->load->model('design/seo_regex');
$required = [
'seo_regex_id' => 0,
'key' => '',
'match' => '',
'replace' => '',
'keyword' => '',
'value' => '',
'sort_order' => 0
];
$post_info = $this->request->post + $required;
if (!$post_info['seo_regex_id']) {
$json['seo_regex_id'] = $this->model_design_seo_regex
->addSeoRegex($post_info);
} else {
$this->model_design_seo_regex->editSeoRegex(
$post_info['seo_regex_id'],
$post_info
);
}
}
}
Example Regex Patterns
// Product pattern
[
'key' => 'product_id',
'match' => '([0-9]+)',
'replace' => 'product-$1',
'keyword' => 'product-{id}',
'value' => '{id}'
]
// Category path pattern
[
'key' => 'path',
'match' => '([0-9_]+)',
'replace' => 'category-$1',
'keyword' => 'category/{path}',
'value' => '{path}'
]
Enabling SEO URLs
Enable in Settings
Go to System → Settings → [Your Store] → Server and enable SEO URLs.$this->model_setting_setting->editSetting('config', [
'config_seo_url' => 1
], $store_id);
Configure .htaccess
Ensure your .htaccess file contains URL rewrite rules:# SEO URL Settings
RewriteEngine On
RewriteBase /
RewriteRule ^sitemap.xml$ index.php?route=extension/feed/google_sitemap [L]
RewriteRule ^googlebase.xml$ index.php?route=extension/feed/google_base [L]
RewriteRule ^system/storage/(.*) index.php?route=error/not_found [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css)
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]
Verify Configuration
Test SEO URLs by visiting a product or category page.
For Nginx servers, use equivalent rewrite rules in your nginx.conf.
Product SEO Configuration
Each product can have custom meta tags:
$product_data = [
'meta_title' => 'MacBook Pro 13-inch - Buy Online',
'meta_description' => 'Shop the latest MacBook Pro 13-inch with M2 chip. Free shipping and 1-year warranty.',
'meta_keyword' => 'macbook, apple, laptop, m2 chip',
'tag' => ['apple', 'laptop', 'macbook']
];
SEO URL Assignment
// Add product SEO URL
$this->model_design_seo_url->addSeoUrl(
'product_id', // Key
$product_id, // Value
'macbook-pro-13-inch-m2-chip', // Keyword
0, // Store ID
1, // Language ID
0 // Sort order
);
Category SEO Configuration
Hierarchical URLs
// Parent category
$this->model_design_seo_url->addSeoUrl(
'path',
'20',
'electronics',
0, 1, 0
);
// Child category
$this->model_design_seo_url->addSeoUrl(
'path',
'20_27',
'electronics/laptops',
0, 1, 0
);
// Grandchild category
$this->model_design_seo_url->addSeoUrl(
'path',
'20_27_35',
'electronics/laptops/macbooks',
0, 1, 0
);
$category_data = [
'meta_title' => 'Laptops - Buy Online | Store Name',
'meta_description' => 'Browse our selection of laptops from top brands.',
'meta_keyword' => 'laptops, computers, notebooks'
];
Multi-Language SEO
English URLs
French URLs
German URLs
[
'language_id' => 1,
'key' => 'product_id',
'value' => '42',
'keyword' => 'macbook-pro-13-inch'
]
[
'language_id' => 2,
'key' => 'product_id',
'value' => '42',
'keyword' => 'macbook-pro-13-pouces'
]
[
'language_id' => 3,
'key' => 'product_id',
'value' => '42',
'keyword' => 'macbook-pro-13-zoll'
]
SEO Best Practices
1. Keyword Guidelines
Create descriptive, keyword-rich URLs:
- Use hyphens (-) to separate words
- Keep URLs short and relevant
- Include primary keywords
- Avoid special characters
- Use lowercase letters
// ✅ Good keywords
'macbook-pro-13-inch-m2'
'mens-running-shoes-nike'
'summer-dresses-2026'
// ❌ Bad keywords
'product123'
'Macbook_Pro_13"'
'MENS-RUNNING-SHOES!!!'
// Title: 50-60 characters
'meta_title' => 'MacBook Pro 13" M2 Chip - Buy Online | Store'
// Description: 150-160 characters
'meta_description' => 'Shop the latest MacBook Pro 13-inch featuring the powerful M2 chip. Fast shipping, 1-year warranty, and expert support.'
// Keywords: 5-10 relevant terms
'meta_keyword' => 'macbook pro, m2 chip, apple laptop, 13 inch, buy macbook'
3. URL Structure
// Logical hierarchy
'/electronics/laptops/macbooks/macbook-pro-13'
// Avoid deep nesting (3-4 levels max)
// ❌ Too deep:
'/home/products/electronics/computers/laptops/apple/macbooks/13-inch/m2/space-gray'
4. Canonical URLs
{# In your template #}
<link rel="canonical" href="{{ canonical }}" />
Programmatic SEO URL Management
Bulk Import SEO URLs
public function importSeoUrls(array $data): void {
$this->load->model('design/seo_url');
foreach ($data as $row) {
$this->model_design_seo_url->addSeoUrl(
$row['key'],
$row['value'],
$row['keyword'],
$row['store_id'],
$row['language_id'],
$row['sort_order']
);
}
}
Auto-Generate SEO URLs
public function generateProductUrl(int $product_id): string {
$this->load->model('catalog/product');
$product_info = $this->model_catalog_product->getProduct($product_id);
if ($product_info) {
// Create keyword from product name
$keyword = $this->createKeyword($product_info['name']);
// Add SEO URL
$this->model_design_seo_url->addSeoUrl(
'product_id',
$product_id,
$keyword,
0,
$this->config->get('config_language_id'),
0
);
return $keyword;
}
}
private function createKeyword(string $name): string {
// Convert to lowercase
$keyword = strtolower($name);
// Replace spaces with hyphens
$keyword = str_replace(' ', '-', $keyword);
// Remove special characters
$keyword = preg_replace('/[^a-z0-9-]/', '', $keyword);
// Remove multiple hyphens
$keyword = preg_replace('/-+/', '-', $keyword);
// Trim hyphens
$keyword = trim($keyword, '-');
return $keyword;
}
Sitemap Generation
Generate XML sitemaps for search engines:
public function generateSitemap(): void {
$this->load->model('catalog/product');
$this->load->model('catalog/category');
$this->load->model('design/seo_url');
$output = '<?xml version="1.0" encoding="UTF-8"?>';
$output .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
// Add products
$products = $this->model_catalog_product->getProducts();
foreach ($products as $product) {
$seo_url = $this->model_design_seo_url->getSeoUrlByKeyValue(
'product_id',
$product['product_id'],
0,
$this->config->get('config_language_id')
);
if ($seo_url) {
$output .= '<url>';
$output .= '<loc>' . $this->url->link('product/product', 'product_id=' . $product['product_id']) . '</loc>';
$output .= '<lastmod>' . date('Y-m-d', strtotime($product['date_modified'])) . '</lastmod>';
$output .= '<changefreq>weekly</changefreq>';
$output .= '<priority>1.0</priority>';
$output .= '</url>';
}
}
$output .= '</urlset>';
// Save to file
file_put_contents(DIR_CATALOG . 'sitemap.xml', $output);
}
Troubleshooting
SEO URLs Not Working
Check .htaccess
Verify .htaccess file exists and contains correct rewrite rules.
Enable mod_rewrite
Ensure Apache mod_rewrite is enabled:sudo a2enmod rewrite
sudo systemctl restart apache2
Check Settings
Confirm SEO URLs are enabled in System → Settings → Server.
Duplicate Keyword Errors
// Check for duplicates before adding
$existing = $this->model_design_seo_url->getSeoUrlByKeyword(
$keyword,
$store_id
);
if ($existing) {
// Append suffix
$keyword .= '-' . $value;
}
404 Errors on SEO URLs
- Verify keyword is correctly stored in database
- Check for typos in keyword
- Ensure entity (product/category) exists and is enabled
- Clear cache