Say I want to link to the medium size on this product: https://demo.sylius.com/en_US/products/slim-fit-men out of the box this is not possible.
URL wise I see three options:
There are all kinds of SEO challenges regarding this, but I think that is out of the scope for this particular problem.
I am most fan of option 3, but both option 2 and option 3 obviously entails more work than option 1.
I basically have two questions:
I'd add option number 4 to it: https://demo.sylius.com/en_US/products/mug-et/variant_id
where variant_id is a route parameter
I would implement this as a plugin. that plugin should have a route and a controller that replaces the current route for product show on shop.
and the plugin should have configurable behavior for how it should work:
also, bear in mind that there are products where the variant is defined by choosing from multiple options; eg: you have a product that is defined by the intersection of 3 options (color, size and material). in this case, the url would be:
https://domain.tld/shop/p/my_product_slug/red/small/cotton
https://domain.tld/shop/p/my_product_slug/red/medium/cotton
https://domain.tld/shop/p/my_product_slug/red/large/cotton
etc.etc.
also, given that product attribute and description is related to product, not to product variant, indexing in google all variants with dedicated URLs could pose a problem, especially if you don't setup a canonical URL. have that in mind too.
Very very good comments, @gabiudrescu
First off thanks for raising this Issue @loevgaard - not being able to link directly to a variant is a huge short coming.
I believe Google reads from the right in terms of priority and interprets / as "hard" separator - perhaps that's what you mean @loevgaard when you state that there's "all kinds of SEO challenges regarding this" and also I admit I'm not an SEO expert. If the above is in fact the case then I would argue that the variant direct links should be constructed like this:
https://domain.tld/category/product/red-large-cotton-my_product_slug
which also makes the URL somewhat human readable.
I realise that adding the variant options before the product slug most likely will over-complicate matters in which case I'd opt for:
https://domain.tld/category/product/my_product_slug-red-large-cotton
You might be able to overcome some of the SEO issues by using canonical links to the product url without the variant in it. The variant urls won’t index, but it also want lead to penalties. The URL’s can still be used in marketing and what not.
Op 28 feb. 2019 om 15:16 heeft Carsten Rose Lundberg notifications@github.com het volgende geschreven:
First off thanks for raising this Issue @loevgaard - not being able to link directly to a variant is a huge short coming.
I believe Google reads from the right in terms of priority and interprets / as "hard" separator - perhaps that's what you mean @loevgaard when you state that there's "all kinds of SEO challenges regarding this" and also I admit I'm not an SEO expert. If the above is in fact the case then I would argue that the variant direct links should be constructed like this:
https://domain.tld/category/product/red-large-cotton-my_product_slug
which also makes the URL somewhat human readable.
I realise that adding the variant options before the product slug most likely will over-complicate matters in which case I'd opt for:
https://domain.tld/category/product/my_product_slug-red-large-cotton
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.
True @stefandoorn for sure a canonical link to the product without variant info should be used as the different variant pages will be too similar hence causing duplicate content flagging.
As stated in the initial issue there will be SEO challenges. However, these challenges won't be the same for every shop. One shop would want to use the canonical solution to the duplicate content problem, another shop would instead create unique content for the variants. I am not sure we should make that choice for them.
Good point and I agree @loevgaard using canonical or not should be configurable
Giving this a second thought and looking at the db model isn't the straight forward solution to add a slug to sylius_product_variant_translation? So that's it's auto generated taking the option_value_translation and product_translation and adding a route to specify that the variant slug is to be used => /category/product/v/red-large-cotton-my-product-slug
If you add a slug and generate it based on the option value translation, you're essentially creating a duplicated value in the database that is not based on a true relationship.
You would have to keep that in sync somehow, by perhaps updating the slug when the options or option values that are related to the variant change.
I would vote against doing that on a database level as the redundancy is not really necessary, however you could do it with some sort of virtual field or a method on an Entity level, maybe.
so, what's next? is this going to be a plugin?
I would love for Sylius to comment on it also, and I have asked @Zales0123 to take a look :)
However, regarding the different URL options, I like yours the best, @gabiudrescu, though I personally like a version like /products/mug-et/variant-slug (i.e. you can write a unique slug for each variant, but it can be auto generated of course) better than /products/mug-et/option-1-value/option-2-value/option-n-value. What do you guys think?
I'm not an SEO expert so I would leave the decision how should these links look like for you, but I would definitely go with it as a plugin :) In my opinion, it should be also kept in mind during the implementation, that it should be probably compatible with @stefandoorn's https://github.com/stefandoorn/SyliusSeoUrlPlugin 🚀
Regarding the configurability: I know it would be great, but my advice is to keep it as simple as possible for the first version (just provide some more SEO-friendly links, it's still a very good benefit) and think about the configurability later 🖖
If you add a slug and generate it based on the option value translation, you're essentially creating a duplicated value in the database that is not based on a true relationship.
You would have to keep that in sync somehow, by perhaps updating the slug when the options or option values that are related to the variant change.
I would vote against doing that on a database level as the redundancy is not really necessary, however you could do it with some sort of virtual field or a method on an Entity level, maybe.
Sorry for the late reply @4c0n . Maybe I wasn't specific enough. I want the slug to be auto generated in the same way the slug is auto generated on the product level - filled out automatically based on the name. Also - same as on the product level - the slug should be locked after creation as changing the slug would cause external links to break and all sorts of SEO issues :)
In essens what I'm rooting for is that what is now variants are elevated into becoming first class citizens. I realise that this is outside the scope of this question but if it where so then this would be a non-issue. In most cases a product isn't a real thing. It's a construct that only becomes real due to it's options/affiliations. E.g. a "red large foo-bar t-shirt" is a tangible product while the "foo-bar t-shirt" is not. So the model should be created bottom up rather than top down. A product "red large foo-bar t-shirt" would have an affiliation called "red" as well as an an affiliation called "large" and it might have an affiliation called "foo-bar t-shirt" in the case that there e.g is also a "red small foo-bar t-shirt". Also the "red large foo-bar t-shirt" might have an affiliation called "t-shirts" and it might have an affiliation called "mens clothing" and so on and so on ... Sorry for the long post which admittedly is out of scope I just had to have it out - accept my apology 😬
@carstenroselundberg I understand what you're getting at, however that seems to apply to the use case where the variants are generated (once).
You're dismissing the technical issue of duplicating a value in the database that will cause unnecessary redundancy and needs to be kept in sync (it would be strange for the slug to remain the same when the product options (and/or their values) change for example). That's the reason I'm saying it should probably not be done on a database level and you cannot guarantee that the identifier (slug or otherwise) will always remain the same when you base it on the product options (perhaps in certain use cases you can, however you'd want the plugin to work for all supported use cases involving variants IMO).
I might be missing something here @4c0n but I'm not seeing how changing options are any different that changing the name of a product? (in which case the slug doesn't change unless you do so manually) So say you have a red t-shirt the slug for that variant would be /red-t-shirt and adding a blue option to the product wouldn't change the options of the red t-shirt would it? I don't know if this helped spark the confusion but I see now that I referenced a wrong table before. I meant that the slug of the variant should reside in sylius_product_variant_translation in exactly the same way as it does in sylius_product_translation for the product level now.
@carstenroselundberg It doesn't change if you use a simple example like that. However when you add more options and later decide to remove an option, it would be a different situation. Don't get me wrong, I'm not saying it is impossible to do, it just doesn't have my preference to do it like that. Especially if you want to look at this from an SEO perspective where you would always like to include the the option values, I think you would want to keep it in sync.
There are probably other edge cases to think of as well.
I will start coding this plugin today, and every Thursday until it's finished. For starters I will create an URL like https://demo.sylius.com/en_US/products/mug-et/{variant_identifier} where the idea is that you can choose your own variant identifier, i.e. code, sluggified name etc
@loevgaard will you make it public here https://github.com/Setono? If so I'll put a watch on it and see if we might be able to help :)
The plugin will be published here: https://github.com/Setono/SyliusVariantLinkPlugin - and be open source :)
I have made a proof of concept now. I am not very satisfied yet, but would like some feedback.
Here is the idea behind the code:
$variant_identifier parameter in the routesylius.product.show event which creates a canonical link to the product: https://github.com/Setono/SyliusVariantLinkPlugin/blob/master/src/EventListener/AddCanonicalSubscriber.phpsylius.product.show event which throws a NotFoundHttpException if the product does not have a variant which matches the given identifier: https://github.com/Setono/SyliusVariantLinkPlugin/blob/master/src/EventListener/VariantExistsSubscriber.phpProductVariantResolverInterface (https://github.com/Setono/SyliusVariantLinkPlugin/blob/master/src/Resolver/ProductVariantResolverInterface.php) which intended use is to return a product variant based on the identifier. This gives you the option to use whatever attribute as an identifier, i.e. a slugified name as @gabiudrescu suggested. I have a made a concrete implementation which uses the code as identifier here: https://github.com/Setono/SyliusVariantLinkPlugin/blob/master/src/Resolver/ProductVariantByCodeResolver.phpWhat are your thoughts?
looks good to me so far.
what it's missing, from my point of view:
how to use section in the readme of the plugin; small and conciseThis issue has been automatically marked as stale because it has not had any recent activity. It will be closed in a week if no further activity occurs. Thank you for your contributions.
Hi @gabiudrescu
a twig function to generate deeplinks in other twig templates
What do you mean by deeplinks? Right now you would be able to use the default path function like so: path('setono_sylius_variant_link_shop_product_variant_show', {'slug': 'PRODUCT SLUG', 'variant_identifier': 'I.E. CODE'}) to generate a link.
yes, one can use path, indeed.
but I was thinking about a custom twig function, like deeplink('product_slug', 'variant_identifier')
not mandatory, ofc.
Hi guys
I just released v0.1 of this plugin: https://github.com/Setono/SyliusVariantLinkPlugin
Could you check it out? :)
On a first glance looks interesting :) README is quite clear on the options :-) Would it work together with my SEO URL plugin out of the box?
Most helpful comment
Hi guys
I just released v0.1 of this plugin: https://github.com/Setono/SyliusVariantLinkPlugin
Could you check it out? :)