One of the most common frustrations for Magento 2 developers and store owners is the sudden appearance of non-SEO-friendly URLs. Instead of a clean path like example.com/accessories/pouches.html, you might see something like example.com/catalog/category/view/s/pouches/id/20/. This usually happens after creating new store views, migrating data, or performing bulk product imports.

In Magento 1, you could simply fix this by reindexing. However, Magento 2 handles URL rewrites differently, and there is no native "regenerate" button in the admin panel. In this guide, you will learn the most effective ways to delete and regenerate URL rewrites using both command-line tools and manual techniques.

Why Magento 2 URL Rewrites Break

URL rewrites in Magento 2 are stored in the url_rewrite database table. When you create a new store view, the system doesn't always automatically generate the SEO-friendly paths for existing products and categories for that specific view.

Additionally, if you have migrated from Magento 1, the "Use Default Value" checkbox for URL keys might be unchecked at the store view level. This prevents the global URL key from propagating, leading to the fallback system path. Understanding whether you need a bulk programmatic fix or a targeted manual fix is the first step to resolving the issue.

For stores with hundreds or thousands of products, manual updates are impossible. The most reliable way to handle this is via a high-quality community extension. The elgentos/regenerate-catalog-urls module is the current industry standard for this task.

Step 1: Installation

Open your terminal and run the following commands to install the module via Composer:

composer require elgentos/regenerate-catalog-urls
php bin/magento setup:upgrade
php bin/magento setup:di:compile

Step 2: Regenerate Product URLs

Once installed, you can regenerate URLs for all products across all store views with a single command:

php bin/magento regenerate:product:url

If you only need to target specific products or a specific store view (for example, store ID 1), you can append arguments:

# Regenerate for products with IDs 1, 2, 3, and 4 for store 1
php bin/magento regenerate:product:url -s1 1 2 3 4

Method 2: Alternative CLI Tools for Categories

If you find that your category URLs are still not updating correctly, you may need a tool specifically designed to handle the category tree hierarchy. Another popular option is the iazel/regenurl extension (or its updated forks).

To regenerate category URL keys specifically, you can use:

php bin/magento iazel:regenerate_urls

Another alternative is the olegkoval/magento2-regenerate_url_rewrites extension. After installation, you can run:

# Regenerate all URL rewrites for all stores
bin/magento ok:urlrewrites:regenerate

# Regenerate for a specific store view (e.g., store ID 2)
bin/magento ok:urlrewrites:regenerate 2

Method 3: The Manual "Toggle" Trick (No Extensions Required)

If you are working on a production environment where you cannot easily install new modules, or if you only have a few categories to fix, you can use a manual trigger method. Magento 2 is designed to regenerate a URL rewrite whenever a category or product is saved with a change to its SEO data.

How to trigger a bulk refresh via Categories:

  1. Navigate to Catalog > Categories.
  2. Select a top-level category.
  3. Scroll down to the Search Engine Optimization section.
  4. Modify the URL Key slightly (e.g., if it is accessories, change it to accessories-x).
  5. Uncheck "Create Permanent Redirect for old URL" to avoid cluttering your database with unnecessary redirects.
  6. Save the category.
  7. Immediately change the URL Key back to the original value (accessories) and save again.

Magento's logic will often cascade this change. When a parent category is updated, it frequently triggers the regeneration of child categories and the products associated with them. Note that for very large categories (over 400-500 items), this operation might time out depending on your server configuration.

Troubleshooting Store View Overrides

If your URLs still won't update after running the commands above, the issue likely lies in your Store View settings.

  1. Go to the product or category in the Admin panel.
  2. Switch the Store View scope in the top-left corner to the specific store that is broken.
  3. Scroll to the URL Key field.
  4. Ensure the Use Default Value checkbox is checked.

If this box is unchecked, Magento assumes you want a custom URL for that specific store and will not regenerate it based on the global attributes. This is a common side effect of data migration tools.

Frequently Asked Questions

Does reindexing regenerate URL rewrites in Magento 2?

No. Unlike Magento 1, the "Catalog URL Rewrites" indexer does not exist in the same way. Reindexing in Magento 2 updates the search index and category products, but it does not rebuild the url_rewrite table from scratch. You must use a CLI tool or save the entity manually.

Will regenerating URLs delete my custom redirects?

If you use the extensions mentioned above, they typically target the request_path for products and categories. However, it is always best practice to back up your url_rewrite table before running any bulk command to ensure your manual redirects (type 301/302) are preserved.

Why are my URLs showing the category ID instead of the name?

This usually indicates that the url_key attribute is missing or the rewrite was never generated for that specific store view. Running the regenerate:product:url command is the fastest way to resolve this.

Wrapping Up

Clean, SEO-friendly URLs are vital for both user experience and search engine rankings. While Magento 2 lacks a native "Regenerate All" button, using a dedicated CLI tool like elgentos/regenerate-catalog-urls is the most efficient way to keep your store's paths organized.

Always remember to clear your cache (php bin/magento cache:flush) after regenerating URLs to ensure the changes are visible on the frontend. By following these steps, you can ensure your store remains professional and optimized for search.