<p>First thing you'll need to do is set up a route that ensures anything for /products/category-name gets routed to the correct template. You can do this from the control panel or via <code>craft/config/routes.php</code></p>

<p>If you do this in your routes.php file you'd need something like this:</p>

<pre><code>return array(
    'products/(.*?)' =&gt; 'products/index',
);
</code></pre>

<p>Which is telling Craft that for any url that contains <code>products/any-characters</code> it should use the <code>products/index</code> template.</p>

<p>Then, on that template, grab the segment that is the category slug</p>

<pre><code>{% set catSegment = craft.request.segment(2) %}
</code></pre>

<p>You'll then need to get the category that has that slug</p>

<pre><code>{% set category = craft.categories.slug(catSegment).first() %}
</code></pre>

<p>You then have a category model you can work with and can use a craft entries tag with a category criteria using</p>

<pre><code>{% set products = craft.entries.relatedTo(category).find() %}
</code></pre>

<p>Loop through <code>products</code> to output your products.</p>

CC BY-SA 4.0
2018-07-11T15:30:25.203Z
Thanks so much for taking the time to reply - it's very much appreciated.
MGX
CC BY-SA 4.0
2018-07-11T15:30:58.023Z
I'm still getting a 404 error for: www.website.com/products/category-name

Using this mark-up on the menu.

{% for category in craft.categories.group('products').level(1).all() %}
<a class="dropdown-item {{ active(category.slug) }}" href="/products/{{ category.slug }}" title="{{ category.title }}">{{ category.title }}</a>
{% endfor %}
MGX
CC BY-SA 4.0
2018-07-11T20:29:44.297Z
Did you set up a route so that Craft knows which template to use?
foamcow
CC BY-SA 4.0
2018-07-12T10:04:24.627Z
Firstly, thanks so much for taking the time to reply - it's very much appreciated.
MGX
CC BY-SA 4.0
2018-07-12T10:17:44.953Z
Yes, I added a new route (via the control panel), specifically for the test category of:
products/(.*?) to load the products/index template
MGX
CC BY-SA 4.0
2018-07-12T10:21:09.203Z
But unfortunately, I still just get a 404 error, unless the URL includes:

?category=

Is this (another) problem with Craft 3?
MGX
CC BY-SA 4.0
2018-07-11T13:01:39.773Z
2018-07-12T08:48:42.037Z
2018-07-12T08:48:42.037Z
foamcow
<p>This code for linking to a category page:</p>

<pre><code>href="/products/?category={{ category.slug }}"
</code></pre>

<p>Generates this URL:  <code>www.website.com/products/?category=category-name</code></p>

<p>Can someone please tell me how to code links in menus (etc) that will produce URLs without the <code>?category=</code> string being included in the URL.  So that the URL would become: <code>www.website.com/products/category-name</code></p>

<p>Many thanks for your help - it is greatly appreciated!</p>

<url>
How to create clean URLs for category strings?
# How to create clean URLs for category strings?

(Asked by: username_0 on 2018-07-11)

This code for linking to a category page:
href="/products/?category={{ category.slug }}"

Generates this URL:  www.website.com/products/?category=category-name
Can someone please tell me how to code links in menus (etc) that will produce URLs without the ?category= string being included in the URL.  So that the URL would become: www.website.com/products/category-name
Many thanks for your help - it is greatly appreciated!

**Tags:** url

---

## 1 answers

### Answer by username_1 on 2018-07-11. Score: 2

First thing you'll need to do is set up a route that ensures anything for /products/category-name gets routed to the correct template. You can do this from the control panel or via craft/config/routes.php
If you do this in your routes.php file you'd need something like this:
return array(
    'products/(.*?)' => 'products/index',
);

Which is telling Craft that for any url that contains products/any-characters it should use the products/index template.
Then, on that template, grab the segment that is the category slug
{% set catSegment = craft.request.segment(2) %}

You'll then need to get the category that has that slug
{% set category = craft.categories.slug(catSegment).first() %}

You then have a category model you can work with and can use a craft entries tag with a category criteria using
{% set products = craft.entries.relatedTo(category).find() %}

Loop through products to output your products.

> **Comments:**
> **username_0**: Thanks so much for taking the time to reply - it's very much appreciated.  
> **username_0**: I'm still getting a 404 error for: www.website.com/products/category-name  Using this mark-up on the menu.  {% for category in craft.categories.group('products').level(1).all() %} <a class="dropdown-item {{ active(category.slug) }}" href="/products/{{ category.slug }}" title="{{ category.title }}">{{ category.title }}</a> {% endfor %}  
> **username_1**: Did you set up a route so that Craft knows which template to use?  
> **username_0**: Firstly, thanks so much for taking the time to reply - it's very much appreciated.  
> **username_0**: Yes, I added a new route (via the control panel), specifically for the test category of: products/(.*?) to load the products/index template  
> **username_0**: But unfortunately, I still just get a 404 error, unless the URL includes:  ?category=  Is this (another) problem with Craft 3?  

---

