Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Canonical PDP slugs #1338

Merged
merged 4 commits into from
Jun 13, 2022
Merged

feat: Canonical PDP slugs #1338

merged 4 commits into from
Jun 13, 2022

Conversation

tlgimenes
Copy link
Contributor

@tlgimenes tlgimenes commented Jun 2, 2022

What's the purpose of this pull request?

This PR implements PDP slugs RFC.

Both FastStore and VTEX's PDP's paths are under /[slug]/p. The difference is what's inside this slug. On VTEX, the slug is the slugified product name, whereas at FastStore:

fastStoreSlug = `${vtexSlug}-${skuId}`

The goal of this PR is to implement a 301 redirect between vtexSlug -> fastStoreSlug so that stores migrating to FastStore from VTEX don't need to worry about SEO or analytics reports

How it works?

The main idea for implementing this is to make Query.product accept the slug locator. This slug locator returns the product in case the slug is a fastStoreSlug. If the slug is a vtexSlug a RedirectError is thrown. This RedirectError is handled on the starter, redirecting the user to the right path.

For this to work I had to export * from 'errors.ts' and connect to portal's search by slug API.

Also, I had to make some changes to the tests since they suffer from race conditions. We could do this part in another PR.

How to test it?

For testing it, chose a product (e.g. /4k-philips-monitor-99988213/p) and make sure that:

  1. The main url is workin (/4k-philips-monitor-99988213/p should display the product)
  2. Old slugs are 301 redirected to the new ones: (/4k-philips-monitor/p -> /4k-philips-monitor-99988213/p)
  3. 404 is returned when entering a non existing product (/4k-philips/p)
  4. 500 is returned when a communication error between platform and the server occurs (/4k-philips-monitor-99988213/p returns 500 when the wifi is off)

Starters Deploy Preview

@tlgimenes tlgimenes requested a review from a team as a code owner June 2, 2022 21:05
@vercel
Copy link

vercel bot commented Jun 2, 2022

Deployment failed with the following error:

Resource is limited - try again in 10 minutes (more than 100, code: "api-deployments-free-per-day").

@codesandbox-ci
Copy link

codesandbox-ci bot commented Jun 2, 2022

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 8e617fa:

Sandbox Source
Store UI Typescript Configuration

@vercel
Copy link

vercel bot commented Jun 2, 2022

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated
faststore ✅ Ready (Inspect) Visit Preview Jun 13, 2022 at 5:23PM (UTC)

title: productName,
description,
canonical: `/${linkText}/p`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like this very much. This doesn't reflect the freedom we give to our users to choose how they're going to name their pages.

Copy link
Contributor Author

@tlgimenes tlgimenes Jun 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, however, there is a tradeoff. Either we make @faststore/api understand about the routing or we make the starter understand this routing.

Making the starter understand about routing at first make sense since it is the one defining the routes. However, is we do that, we also need to make the if/else statement for routing the user to the new slug type, leaking vtex logic into the starter.

packages/api/src/platforms/vtex/resolvers/query.ts Outdated Show resolved Hide resolved

export const canonicalFromProduct = ({ items, linkText }: Product) => {
// Sort by id so we always use the same canonical regardless of sku availability/ordering
const [{ itemId }] = items.sort(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can lead to a wrong correspondence between a previous SKU (from SF or Portal) and a different SKU here, harming SEO due to the change in the page content.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can u exemplify this with a real use case?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Search might not follow itemId order. So on Store Framework, the indexed SKU would be eg. id 2, but here, it'd be id 1, what could make the product name and other attributes change when users are redirected from /slug/p (previously implicit skuId 2) to /slug-${skuId}/p (explicit skuId 1).

Copy link
Contributor Author

@tlgimenes tlgimenes Jun 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the reasoning behind this was:
Suppose you have two skus, A and B. Let's say today A is available and B is out of stock. This means, that, when we request for the product, the items array returned by the search API will be [A, B]. This makes the canonical be /slug-A/p. Now, suppose that A gets out of stock and B enters the stock. Now, when requesting for the product, the items array would be: [B,A], making the canonical be /slug-B/p.
This sort prevents this behavior making the canonical always be consistently /slug-A/p.

The tradeoff in here is redirecting the user to an out of stock sku vs changing the canonical of a page. I'm not sure which approach is worse for conversion (breaking SEO vs redirecting the user to an out of stock product)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I think redirecting to the same consistent page sounds better to me, even if that means it'll be out of stock. But isn't that a search config? Can't we force the items to be returned in the same order, regardless of availability? I think that's the best scenario.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I'll remove the sort then

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that's what I meant, Gimenes. Does this mean that, in your example, because of the availability status, another sku can take the first position?

@vercel
Copy link

vercel bot commented Jun 8, 2022

Deployment failed with the following error:

Resource is limited - try again in 33 minutes (more than 100, code: "api-deployments-free-per-day").

@tlgimenes tlgimenes force-pushed the fix/pdp-migration branch from 576e612 to 3a90525 Compare June 10, 2022 15:37
@tlgimenes tlgimenes changed the base branch from main to feat/export-errors June 10, 2022 19:56
@tlgimenes tlgimenes force-pushed the fix/pdp-migration branch from 3a90525 to a68a447 Compare June 10, 2022 19:58
Base automatically changed from feat/export-errors to main June 13, 2022 17:06
@tlgimenes tlgimenes force-pushed the fix/pdp-migration branch from a0530f4 to 03d8bf2 Compare June 13, 2022 17:14
tlgimenes and others added 2 commits June 13, 2022 14:16
Co-authored-by: Emerson Laurentino <emerson@laurentino.co>
@tlgimenes tlgimenes merged commit ec807bb into main Jun 13, 2022
@tlgimenes tlgimenes deleted the fix/pdp-migration branch June 13, 2022 17:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants