Seo urls routing
Skill mvstepanek/nextjs-ecommerce-seo-skills/skills/seo-urls-routing
SEO skills for AI coding assistants (Claude Code + GitHub Copilot) targeting Next.js e-commerce sites
npx -y skills add mvstepanek/nextjs-ecommerce-seo-skills --skill seo-urls-routingAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
URL structure and Next.js routing rules for SEO. Use when creating new routes, pages, modifying URL patterns, adding dynamic segments, or working with pagination and query parameters.
SKILL.md
6.3 KB, as published. Nobody here has run it
URL Structure & Routing SEO Guidelines
Technical rules for URL patterns and routing in a Next.js e-commerce site.
URL Pattern
A common e-commerce URL pattern is /{lang}-{COUNTRY}/{section}/{id}/{slug}. Adapt to your project's actual structure:
Example (adapt paths to your project):
- Homepage:
/en-US/ - Category:
/en-US/categories/electronics - Subcategory:
/en-US/categories/electronics/wireless-headphones - Product:
/en-US/products/123/blue-widget-pro-3000 - Static pages:
/en-US/contact-us
Locale Prefix Rules
- Every page MUST have a locale prefix — never serve content at
/products/123without a locale - Redirect root
/to the detected or default locale (see seo-hreflang skill for middleware pattern) - Locale format: lowercase language, uppercase country —
en-GB,de-DE,fr-CH - Never hardcode a locale — always derive from route params or config
// GOOD — locale from route params
// [locale]/products/[id]/[slug]/page.tsx
export default function ProductPage({ params }: { params: { locale: string; id: string; slug: string } }) {
// locale is dynamic
}
// BAD — hardcoded locale
const url = '/en-US/products/' + id; // Breaks for other locales
Slug Rules
- Lowercase only —
blue-widget-pro-3000, neverBlue-Widget-Pro-3000 - Hyphen-separated —
wireless-headphones, notwireless_headphonesorwirelessheadphones - No special characters — no encoded characters, accents, or symbols in slugs
- Derived from product name/model — slugs should be human-readable and include the product identifier
- Stable — once a slug is published and indexed, do not change it without a 301 redirect from the old URL
Category URLs
Prefer path-based segments for subcategories:
// PREFERRED — path-based
/en-US/categories/electronics/wireless-headphones
// ACCEPTABLE — query-based (common in existing codebases)
/en-US/categories/electronics?type=wireless-headphones
Path-based URLs are better for SEO because:
- Search engines weight URL path words more than query params
- Easier to set up breadcrumbs and URL hierarchy
- Cleaner for users to read and share
Pagination
- Use
?page=Nquery parameter for paginated pages - Page 1 canonical must NOT include
?page=1— the canonical should be the base URL without the page param - Subsequent pages should have a self-referencing canonical (
?page=2points to?page=2) rel="next"andrel="prev"are not used by Google (dropped in 2019). Bing and some other engines still support them. Including them is low-effort and harmless, but don't rely on them for Google — proper canonical URLs and sitemap inclusion are more important for paginated content.
import { SITE_URL } from '@/config/site';
export async function generateMetadata({ params, searchParams }: Props): Promise<Metadata> {
const page = Number(searchParams.page) || 1;
const basePath = `${SITE_URL}/${params.locale}/categories/${params.slug}`;
return {
alternates: {
canonical: page === 1 ? basePath : `${basePath}?page=${page}`,
},
other: {
...(page > 1 && { 'prev': page === 2 ? basePath : `${basePath}?page=${page - 1}` }),
...(hasNextPage && { 'next': `${basePath}?page=${page + 1}` }),
},
};
}
Search URLs
- Search pages are blocked by robots.txt:
Disallow: /*/search/ - Also add
noindexto search result pages as a fallback — if robots.txt is ever changed or removed, thenoindextag ensures these pages stay out of the index. Note: while robots.txt is active, Google cannot see thenoindextag (it blocks crawling entirely), so both protections do not work simultaneously.
// Search page (any router)
export const metadata: Metadata = {
robots: { index: false, follow: true }, // noindex, follow
};
Why: Search results pages create near-infinite URL combinations, which wastes crawl budget and creates thin content.
Trailing Slashes
- Be consistent — pick one convention and enforce it site-wide
- Configure in next.config.js to enforce consistency:
// next.config.js
module.exports = {
trailingSlash: false, // or true — pick one and stick with it
};
- If you change the trailing slash setting, set up redirects from old URLs to new ones
Dynamic Routes & Static Generation
- Use
[id]and[slug]segments for dynamic content - Use
generateStaticParamsto pre-render known pages at build time:
export async function generateStaticParams() {
const products = await getAllProducts();
return products.map(product => ({
locale: product.locale,
id: product.id,
slug: product.slug,
}));
}
- Use ISR (
revalidate) for pages that update frequently (prices, stock):
export const revalidate = 300; // Regenerate every 5 minutes
Query Parameters & Filters
- Granular filter combinations should not be indexed — pages like
?color=red&size=large&weight=5kgshould:- Have their canonical set to the base category URL (without filter params), AND/OR
- Use
noindex, followto prevent indexing while allowing link discovery
- Useful single-filter pages can remain indexable — if the filter represents a real search intent (e.g.
?type=wireless), keep it indexed - Sort parameters (
?sort=price-asc) — the canonical should always point to the base URL - UTM parameters — should be ignored by canonical (canonical never includes UTM params)
Common Technical Anti-Patterns
- Missing locale prefix — every URL must start with
/{lang}-{COUNTRY}/ - Hardcoded locale strings — use route params, never hardcode
en-US - Page 1 with
?page=1— the canonical for page 1 is the clean URL without pagination - Changing slugs without redirects — if a product slug changes, 301 redirect the old URL
- Uppercase in slugs — always lowercase
- Indexable search pages — search results must be noindex
- UTM params in canonicals — canonical URLs must never include tracking parameters