Magento 1 had an indexer which regenerate url rewrites automatically each run of that indexer. This was quite comfortable. The only problem were shops with a lot of products. The more products and the more rewrites, the longer this indexer runs. So for performance optimization it was a good idea to remove this indexer for Magento 2. But this has other drawbacks…
Problem
An url rewrite is required for seo optimized shop urls.
Magento 2 do not automatically create rewrites. They are only computed if you do an action like save category. This makes sense if you create categories and products in you backend. If you import these things by code, you have to save all categories manually after each import. No solution for a programmer…
Solution
A quite simple solution is to use a ready to run Magento 2 module which does exactly the work of an rewrite indexer. A programmer did that an offers his module magento2-regenurl on github. You can call this regeneration by code or from command line. A better solution is to do it by code in your own importer module. The regeneration is quite simple:
foreach($list as $product) {
if($store_id === Store::DEFAULT_STORE_ID)
$product->setStoreId($store_id);
$this->urlPersist->deleteByData([
UrlRewrite::ENTITY_ID => $product->getId(),
UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE,
UrlRewrite::REDIRECT_TYPE => 0,
UrlRewrite::STORE_ID => $store_id
]);
try {
$this->urlPersist->replace(
$this->productUrlRewriteGenerator->generate($product)
);
} catch(\Exception $e) {
$out->writeln('Duplicated url for '. $product->getId() .'');
}
}
As you can see Magento 2 offers you a model for regenerate url rewrites
\Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator
(productUrlRewriteGenerator) which you can inject into your model. This generated url rewrite can be replaced by \Magento\UrlRewrite\Model\UrlPersistInterface
(urlPersist). You can run this in a loop for all products after import or for each single product after a change.
You find url rewrites in url_rewrite table in you database. This is exactly the same as in Magento 1.
I recently found this Magento 2 Module on GitHub
which fixes all my problems. I can recomend it. You can simply regenerate all your url rewrites for products and categories with the following command:
bin/magento ok:urlrewrites:regenerate
I Hope that helps!