Skip to content

Commit

Permalink
feat: Canonical PDP slugs (#87)
Browse files Browse the repository at this point in the history
  • Loading branch information
tlgimenes authored Jun 13, 2022
1 parent db5c414 commit a88ecbc
Show file tree
Hide file tree
Showing 11 changed files with 39 additions and 50 deletions.
7 changes: 4 additions & 3 deletions @generated/graphql/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2767,6 +2767,7 @@ export type CollectionPageQueryQuery = {
titleTemplate: string | null
title: string | null
description: string | null
siteUrl: string | null
} | null
} | null
}
Expand Down Expand Up @@ -2799,18 +2800,17 @@ export type ProductPageQueryQuery = {
}

export type ServerProductPageQueryQueryVariables = Exact<{
id: Scalars['String']
slug: Scalars['String']
}>

export type ServerProductPageQueryQuery = {
product: {
slug: string
sku: string
gtin: string
name: string
description: string
id: string
seo: { title: string; description: string }
seo: { title: string; description: string; canonical: string }
brand: { name: string }
breadcrumbList: {
itemListElement: Array<{ item: string; name: string; position: number }>
Expand Down Expand Up @@ -2848,6 +2848,7 @@ export type HomePageQueryQuery = {
title: string | null
description: string | null
titleTemplate: string | null
siteUrl: string | null
} | null
} | null
}
Expand Down
6 changes: 3 additions & 3 deletions @generated/graphql/persisted.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"ProductGalleryQuery": "query ProductGalleryQuery($first: Int!, $after: String!, $sort: StoreSort!, $term: String!, $selectedFacets: [IStoreSelectedFacet!]!) {\n search(\n first: $first\n after: $after\n sort: $sort\n term: $term\n selectedFacets: $selectedFacets\n ) {\n products {\n pageInfo {\n totalCount\n }\n edges {\n node {\n id: productID\n slug\n sku\n brand {\n brandName: name\n name\n }\n name\n gtin\n isVariantOf {\n productGroupID\n name\n }\n image {\n url\n alternateName\n }\n offers {\n lowPrice\n offers {\n availability\n price\n listPrice\n quantity\n seller {\n identifier\n }\n }\n }\n }\n }\n }\n facets {\n key\n label\n type\n values {\n label\n value\n selected\n quantity\n }\n }\n }\n}\n",
"CollectionPageQuery": "query CollectionPageQuery {\n site {\n siteMetadata {\n titleTemplate\n title\n description\n }\n }\n}\n",
"CollectionPageQuery": "query CollectionPageQuery {\n site {\n siteMetadata {\n titleTemplate\n title\n description\n siteUrl\n }\n }\n}\n",
"ServerCollectionPageQuery": "query ServerCollectionPageQuery($slug: String!) {\n collection(slug: $slug) {\n seo {\n title\n description\n }\n breadcrumbList {\n itemListElement {\n item\n name\n position\n }\n }\n meta {\n selectedFacets {\n key\n value\n }\n }\n }\n}\n",
"ProductPageQuery": "query ProductPageQuery {\n site {\n siteMetadata {\n title\n description\n titleTemplate\n siteUrl\n }\n }\n}\n",
"ServerProductPageQuery": "query ServerProductPageQuery($id: String!) {\n product(locator: [{key: \"id\", value: $id}]) {\n id: productID\n slug\n seo {\n title\n description\n }\n brand {\n name\n }\n sku\n gtin\n name\n description\n breadcrumbList {\n itemListElement {\n item\n name\n position\n }\n }\n image {\n url\n alternateName\n }\n offers {\n lowPrice\n highPrice\n priceCurrency\n offers {\n availability\n price\n priceValidUntil\n priceCurrency\n itemCondition\n seller {\n identifier\n }\n listPrice\n }\n }\n isVariantOf {\n productGroupID\n name\n }\n additionalProperty {\n propertyID\n name\n value\n valueReference\n }\n }\n}\n",
"HomePageQuery": "query HomePageQuery {\n site {\n siteMetadata {\n title\n description\n titleTemplate\n }\n }\n}\n",
"ServerProductPageQuery": "query ServerProductPageQuery($slug: String!) {\n product(locator: [{key: \"slug\", value: $slug}]) {\n id: productID\n seo {\n title\n description\n canonical\n }\n brand {\n name\n }\n sku\n gtin\n name\n description\n breadcrumbList {\n itemListElement {\n item\n name\n position\n }\n }\n image {\n url\n alternateName\n }\n offers {\n lowPrice\n highPrice\n priceCurrency\n offers {\n availability\n price\n priceValidUntil\n priceCurrency\n itemCondition\n seller {\n identifier\n }\n listPrice\n }\n }\n isVariantOf {\n productGroupID\n name\n }\n additionalProperty {\n propertyID\n name\n value\n valueReference\n }\n }\n}\n",
"HomePageQuery": "query HomePageQuery {\n site {\n siteMetadata {\n title\n description\n titleTemplate\n siteUrl\n }\n }\n}\n",
"SearchPageQuery": "query SearchPageQuery {\n site {\n siteMetadata {\n titleTemplate\n title\n description\n }\n }\n}\n",
"ValidateCartMutation": "mutation ValidateCartMutation($cart: IStoreCart!) {\n validateCart(cart: $cart) {\n order {\n orderNumber\n acceptedOffer {\n seller {\n identifier\n }\n quantity\n price\n listPrice\n itemOffered {\n sku\n name\n image {\n url\n alternateName\n }\n brand {\n name\n }\n isVariantOf {\n productGroupID\n name\n }\n gtin\n additionalProperty {\n propertyID\n name\n value\n valueReference\n }\n }\n }\n }\n messages {\n text\n status\n }\n }\n}\n",
"BrowserProductQuery": "query BrowserProductQuery($locator: [IStoreSelectedFacet!]!) {\n product(locator: $locator) {\n id: productID\n sku\n name\n gtin\n description\n isVariantOf {\n productGroupID\n name\n }\n image {\n url\n alternateName\n }\n brand {\n name\n }\n offers {\n lowPrice\n offers {\n availability\n price\n listPrice\n seller {\n identifier\n }\n }\n }\n breadcrumbList {\n itemListElement {\n item\n name\n position\n }\n }\n additionalProperty {\n propertyID\n name\n value\n valueReference\n }\n }\n}\n",
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Added
- 301 redirects when visiting old VTEX product routes ([#87](https://github.com/vtex-sites/gatsby.store/pull/87))

### Changed

Expand Down
16 changes: 5 additions & 11 deletions cypress/integration/seo.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

import { options } from '../global'
import { cypress } from '../../store.config'
import { cypress, storeUrl } from '../../store.config'

const { pages } = cypress

Expand Down Expand Up @@ -35,7 +35,7 @@ describe('Home Page Seo', () => {
cy.get('link[rel="canonical"]')
.should('exist')
.should(($link) => {
expect($link.attr('href')).to.eq(`https://${window.location.host}/`)
expect($link.attr('href')).to.eq(storeUrl)
})
})

Expand Down Expand Up @@ -101,9 +101,7 @@ describe('Product Page Seo', () => {
cy.get('link[rel="canonical"]')
.should('exist')
.should(($link) => {
expect($link.attr('href')).to.eq(
`https://${window.location.host}${pages.pdp}`
)
expect($link.attr('href')).to.eq(`${storeUrl}${pages.pdp}`)
})
})

Expand Down Expand Up @@ -193,9 +191,7 @@ describe('Collection Page Seo', () => {
cy.get('link[rel="canonical"]')
.should('exist')
.should(($link) => {
expect($link.attr('href')).to.eq(
`https://${window.location.host}${pages.collection}/`
)
expect($link.attr('href')).to.eq(`${storeUrl}${pages.collection}`)
})
})

Expand Down Expand Up @@ -250,9 +246,7 @@ describe('Filtered Collection Page Seo', () => {
cy.get('link[rel="canonical"]')
.should('exist')
.should(($link) => {
expect($link.attr('href')).to.eq(
`https://${window.location.host}${pages.collection}/`
)
expect($link.attr('href')).to.eq(`${storeUrl}${pages.collection}`)
})
})

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"@envelop/graphql-jit": "^1.1.1",
"@envelop/parser-cache": "^2.2.0",
"@envelop/validation-cache": "^2.2.0",
"@faststore/api": "^1.9.6",
"@faststore/api": "^1.9.7",
"@faststore/sdk": "^1.9.4",
"@faststore/ui": "^1.9.4",
"@vtex/graphql-utils": "^1.8.42",
Expand Down
7 changes: 2 additions & 5 deletions src/pages/[...slug].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ function Page(props: Props) {
const {
data: { site },
serverData,
location: { host },
slug,
} = props

Expand All @@ -73,10 +72,7 @@ function Page(props: Props) {
const { page } = searchParams
const title = collection?.seo.title ?? site?.siteMetadata?.title ?? ''
const pageQuery = page !== 0 ? `?page=${page}` : ''
const canonical =
host !== undefined
? `https://${host}/${slug}/${pageQuery}`
: `/${slug}/${pageQuery}`
const canonical = `${site?.siteMetadata?.siteUrl}/${slug}${pageQuery}`

return (
<SearchProvider
Expand Down Expand Up @@ -147,6 +143,7 @@ export const querySSG = graphql`
titleTemplate
title
description
siteUrl
}
}
}
Expand Down
28 changes: 12 additions & 16 deletions src/pages/[slug]/p.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,21 @@ function Page(props: Props) {
const {
data: { site },
serverData,
location: { host },
slug,
} = props

// No data was found
if (serverData === null) {
return null
}

const { product } = serverData
const title = product?.seo.title ?? site?.siteMetadata?.title ?? ''
const description =
product?.seo.description ?? site?.siteMetadata?.description ?? ''
const {
product,
product: { seo },
} = serverData

const canonical =
host !== undefined ? `https://${host}/${slug}/p` : `/${slug}/p`
const title = seo.title || site?.siteMetadata?.title || ''
const description = seo.description || site?.siteMetadata?.description || ''
const canonical = `${site?.siteMetadata?.siteUrl}${seo.canonical}`

return (
<>
Expand All @@ -58,7 +57,7 @@ function Page(props: Props) {
language={locale}
openGraph={{
type: 'og:product',
url: `${site?.siteMetadata?.siteUrl}${slug}`,
url: canonical,
title,
description,
images: product.image.map((img) => ({
Expand Down Expand Up @@ -131,21 +130,20 @@ export const querySSG = graphql`
`

export const querySSR = gql`
query ServerProductPageQuery($id: String!) {
product(locator: [{ key: "id", value: $id }]) {
query ServerProductPageQuery($slug: String!) {
product(locator: [{ key: "slug", value: $slug }]) {
id: productID
slug
seo {
title
description
canonical
}
brand {
name
}
slug
sku
gtin
name
Expand Down Expand Up @@ -191,13 +189,11 @@ export const getServerData = async ({
params: Record<string, string>
}) => {
const ONE_YEAR_CACHE = `s-maxage=31536000, stale-while-revalidate`
const id = slug.split('-').pop()

const { isNotFoundError } = await import('@faststore/api')
const { execute } = await import('src/server/index')
const { data, errors = [] } = await execute({
operationName: querySSR,
variables: { id },
variables: { slug },
})

const notFound = errors.find(isNotFoundError)
Expand Down
4 changes: 2 additions & 2 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,12 @@ export type Props = PageProps<HomePageQueryQuery>
function Page(props: Props) {
const {
data: { site },
location: { pathname, host },
} = props

const { locale } = useSession()

const title = site?.siteMetadata?.title ?? ''
const siteUrl = `https://${host}${pathname}`
const siteUrl = `${site?.siteMetadata?.siteUrl}`

return (
<>
Expand Down Expand Up @@ -121,6 +120,7 @@ export const querySSG = graphql`
title
description
titleTemplate
siteUrl
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/server/index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
/* eslint-disable react-hooks/rules-of-hooks */
import {
envelop,
useAsyncSchema,
useExtendContext,
useMaskedErrors,
useAsyncSchema,
} from '@envelop/core'
import type { FormatErrorHandler } from '@envelop/core'
import { useGraphQlJit } from '@envelop/graphql-jit'
import { useParserCache } from '@envelop/parser-cache'
import { useValidationCache } from '@envelop/validation-cache'
import { getContextFactory, getSchema, isFastStoreError } from '@faststore/api'
import type { Options as APIOptions } from '@faststore/api'
import { GraphQLError } from 'graphql'
import type { FormatErrorHandler } from '@envelop/core'
import type { Options as APIOptions } from '@faststore/api'

import persisted from '../../@generated/graphql/persisted.json'
import storeConfig from '../../store.config'
Expand Down
4 changes: 2 additions & 2 deletions store.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ module.exports = {
server: process.env.BASE_SITE_URL || 'http://localhost:9000',
pages: {
home: '/',
pdp: '/apple-magic-mouse-99988212/p',
pdp: '/apple-magic-mouse/p',
collection: '/office',
},
},
Expand All @@ -34,7 +34,7 @@ module.exports = {
cypress: {
pages: {
home: '/',
pdp: '/apple-magic-mouse-99988212/p',
pdp: '/apple-magic-mouse/p',
collection: '/office',
collection_filtered:
'/office/?category-1=office&marca=acer&facets=category-1%2Cmarca',
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1974,10 +1974,10 @@
minimatch "^3.0.4"
strip-json-comments "^3.1.1"

"@faststore/api@^1.9.6":
version "1.9.6"
resolved "https://registry.yarnpkg.com/@faststore/api/-/api-1.9.6.tgz#c94c32fc2fb2098d6016914475b508e3f9afcf42"
integrity sha512-J3zi7g+szhQBLU9jgYgFDwP4oQFJB+4BpFx/Qvtn6voRsScRoP1Sz9Yk/1lZ2t1T5IZFTn4Qw/oudK2ii5+hMA==
"@faststore/api@^1.9.7":
version "1.9.7"
resolved "https://registry.yarnpkg.com/@faststore/api/-/api-1.9.7.tgz#00c2ecad235a273860035c87e4be3b9c3dea4115"
integrity sha512-khpdJ7J4W2P9SZdF9cesfceEjrK0E0Z6xLd6hZmZEJXba2vhuvNHP1zgUYpFVkEawT1IBN7y0akLp7EygqPp5w==
dependencies:
"@graphql-tools/schema" "^8.2.0"
"@rollup/plugin-graphql" "^1.0.0"
Expand Down

1 comment on commit a88ecbc

@vercel
Copy link

@vercel vercel bot commented on a88ecbc Jun 13, 2022

Choose a reason for hiding this comment

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

Please sign in to comment.