18-09-2026

URL structure – how to build SEO- and user-friendly addresses

URL structure – how to build SEO- and user-friendly addresses

UX Research without guesswork: how to match a UX research method to your business need technical SEOthat can cause chaos across a site’s entire lifetime. In my work I regularly come across URLs thrown together ad hoc, with no plan, that need a migration and hundreds of 301 redirects a year later. And every migration like that risks a temporary visibility drop. It’s worth deciding on your URL structure once, at the start, and sticking with it.

What a URL is and what it’s made of

Let’s go quickly through the basics. A URL (Uniform Resource Locator) is a standardized address for a resource on the web, or in plain terms, the address of a specific page, file or image online. Every resource has its own unique address. The browser knows where to find it precisely because of the URL.

A complete URL structure looks like this:

Schemat kompletnej struktury adresu URL

Protocol, domain, path – the anatomy of a URL

  • Protocol (https://) – defines how the browser and server communicate. HTTPS is the absolute minimum today; no SSL certificate directly affects the security of the data being transmitted.
  • Domain – the site’s unique name. It consists of an optional subdomain (say blog., shop.), the site’s own name, and a top-level domain (TLD): .com, .net, .org.
  • Path – a page’s location in the directory structure, say /blog/post-name/.
  • Query parameters – a string starting with ?, passes data to the server, say ?sort=price&page=2. Used for filtering products and UTM campaigns.
  • the fragment (commonly called an anchor) – marked with #, scrolls the page to a specific section after loading. It never reaches the server, it’s an instruction for the browser only.

Google describes its URL structure requirements and recommendations in the official Search Central documentation. It’s worth checking out, but Google’s documentation is only a starting point, one worth pairing with proven best practices, which I’ll share with you now.

What friendly URLs are and how to build them with SEO in mind

A friendly URL (in English: friendly URL) is one an internet user can read and guess what’s behind it.

The most important things to know:

  • Always lowercase – /Category/ i /category/ are two different addresses for a lot of servers. One of them will probably return a 404.
  • A hyphen instead of a space or underscore – Google treats a hyphen as a word separator. An underscore (_) doesn’t always work the same way, and a space in a URL gets encoded as +, which looks terrible. The most famous mistake of this kind on the Polish internet can be found on Ceneo, where the scale of the site meant nobody ever dared fix it. In my opinion, rightly so, it’s too late for that now.
  • No accented characters – offer-for-small-businesses becomes something like offer-for-small-bus%C4%B1nesses. Always write without diacritics: offer-for-small-businesses.
  • No system-generated IDs – /product?id=4827&ref=home tells neither the user nor the crawler anything.
  • The address should reflect the page’s content – both the user and the search engine crawler should be able to tell what a page is about from the URL alone. /blog/image-optimization/ says everything. /node/4827 – says nothing.
  • An inconsistent trailing slash – this concerns the / / at the very end of the address. domain.com/blog/post-name/ i domain.com/blog/post-name are two different addresses for a server. If both are accessible with no redirect between them, you have an internal duplicate. Pick one convention and stick to it across the whole site. Most CMSs handle this automatically, but it’s worth checking during an audit.
  • Dates in a URL – /blog/2024/05/post-name/ looks innocent enough until you want to update the content in 2026. The date stays in the URL, the article’s content is fresh, and you have a branding problem and an analytics problem at the same time. The exception is Google News, where a date in the address is one of the freshness signals and genuinely makes sense. If you’re not running a news site, dates in URLs are dead weight.

Bad:

domain.com/category/products?id=4827&sort=asc&filter=none&page=1

Good:

domain.com/c/category-name/

How to build a URL directory structure

This is where my approach differs a bit from most SEO guides. It isn’t only about a URL looking nice, it’s about the directory structure helping you understand what’s happening on the site.

Directories as an analytics tool

I always recommend splitting into directories, and it isn’t only about aesthetics. That way I can easily measure traffic from different parts of the site.

When I have addresses like:

  • /blog/ – articles (informational terms)
  • /k/ – categories (commercial terms)
  • /p/ – products (transactional terms)

I can filter traffic by these prefixes in Google Analytics or Google Search Console within seconds. That lets me see whether visibility growth is just a well-run blog, or whether visibility on commercial and transactional terms is growing too. That’s part of my approach to data-driven SEO – I base decisions on concrete data, not gut feeling.

Flat or nested – how a site’s URL structure should look

There’s not much to belabor here: the structure should be flat, period.

Instead of:

domain.com/c/electronics/laptops/gaming/

Use:

domain.com/c/gaming-laptops/

A deep directory hierarchy sounds logical on paper. In practice it complicates URL management, lengthens addresses, and creates headaches every time you reorganize your catalog. One level of splitting, beyond the main prefix, is usually enough.

The duplicate problem with products in multiple categories

This is one of the more common mistakes I see in SEO audits. It starts innocently enough, a product fits two categories, so someone assigns it to both. And suddenly you have:

domain.com/p/electronics/sony-wh1000xm5/ domain.com/p/phone-accessories/sony-wh1000xm5/

The same product, the same content, two different URLs. To search crawlers, that’s an internal duplicate. You can fix it with a canonical tag, but in this specific case it’s better not to let the situation arise at all. If I use a directory structure for products, a product should live at one, fixed address, regardless of how many categories it’s assigned to in the system.

The exact same problem applies to categories. Imagine an electronics store where “wireless headphones” logically fits both electronics and mobile accessories:

domain.com/c/electronics/wireless-headphones/ domain.com/c/phone-accessories/wireless-headphones/

The category wireless-headphones – identical content, two URLs, two addresses to index, split link equity. And neither one will be as strong as a single consolidated one.

The solution is simple and follows directly from what I said earlier: a flat structure. Instead of pushing the category into a parent hierarchy, I give it one, fixed address:

domain.com/c/wireless-headphones/

Done. There’s no second URL, because there’s no parent in the path. I build the connection between “headphones” and “electronics” or “phone accessories” through internal linking and navigation, not the URL.

Schemat przedstawiający problem duplikacji URL

Filters and parameters – a trap for crawlers

Dynamic URLs from product filtering are, in my view, the biggest and most often overlooked problem in online stores. Every combination of active filters (color, size, material, sorting) can generate a separate URL:

domain.com/c/dresses/?color=red&size=M&material=cotton&sort=price_asc

A store with five filters and ten options each can produce thousands of unique addresses leading to identical or near-identical content that way. That wastes crawl budget: instead of indexing valuable pages, Google’s crawlers go in circles through filter variants. This gets solved through robots.txt or meta robots noindex on parameter pages, but that’s a topic for its own posts; each of those tools has its own rules and limits. I’m flagging it here because the problem starts directly in the URL structure.

URL structure across different CMSs

Every platform approaches URLs a bit differently. I’ll walk through a few of the ones I run into most often:

WordPress / WooCommerce

Full freedom, which is both an advantage and a trap. Nobody imposes a structure, so you can set anything at all. Which is exactly why it’s worth setting it deliberately from the start. I recommend the split above: /blog/, /k/, /p/ and a flat hierarchy in product categories. This is configured through WordPress’s permalink settings, with the WooCommerce structure refined via Yoast SEO or Rank Math.

Shoper

Characteristic of this platform is the /pl/ segment (or another language version) at the start of the path, followed by a split into /p/ (product), /c/ (category), /blog/ (blog). You can override the paths manually, but in most cases you don’t need to. The default logic is readable and fits analytics well, these prefixes do part of the organizational work for you.

PrestaShop

A similar situation to Shoper; the URL generator is configurable in the admin panel. Make sure “friendly URL” mode is enabled: it’s on by default in newer versions, but you can sometimes find it disabled on older installations. It’s also worth checking whether URLs with and without categories create product duplicates.

Shopify

Here you have the least say. The platform enforces a fixed split:

  • /products/product-name – products
  • /collections/collection-name – categories
  • /blogs/blog/post-name – blog
  • /pages/page-name – static pages

You can’t change these prefixes; they’re built into the platform’s architecture. What you control is the slug after the last slash.

There’s one nuance worth noting, Shopify generates two URLs for products at the same time – /products/product (canonical) and /collections/collection/products/product (the one used in category navigation). That’s a potential duplicate. Fortunately Shopify sets the canonical tag automatically to the shorter address /products/product – so the problem is handled by the platform, as long as you don’t get in its way.

On prefix length: /collections/ is 13 characters, /k/ is 3. The rule that the shorter the URL, and the earlier a keyword appears in it, the better, applies here. Shopify doesn’t optimize for this. But the slug itself, the part you can edit, should be as short as possible and lead with the keyword as early as it can. The rest is the framework you have to live with.

Overall, Shopify isn’t ideal for URLs, but it’s workable, especially since the forced split into /products/, /collections/ i /blogs/ gives you a readable structure for analytics automatically. You get ready-made segments with zero configuration.

Changing URLs after the fact always costs you

URL structure is one of those SEO decisions that’s hardest to reverse after the fact. 301 redirects technically solve the problem, but every URL migration is a risk, even a well-executed one can temporarily lower visibility. Better to design it properly once, up front, than to come back to it a year later with a broken structure and a hundred addresses to redirect.

If you’re building a site from scratch and don’t know how to set up the structure for your CMS, or you already have a live site and want to check whether your URLs are causing problems, get in touch.

Sign up for our newsletter and stay up to date
with the world of CRO and UX!