Skip to content

Commit c931e36

Browse files
del15881del22123
andauthored
PWA-3642: Canonical url support (#4597)
Co-authored-by: Bharathidasan Elangovan <del22123@adobe.com>
1 parent f5e87ae commit c931e36

11 files changed

Lines changed: 55 additions & 11 deletions

File tree

packages/peregrine/lib/talons/RootComponents/Category/__tests__/__snapshots__/useCategory.spec.js.snap

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ Object {
3434
},
3535
[MockFunction],
3636
],
37+
"storeConfig": Object {
38+
"grid_per_page": 12,
39+
},
3740
}
3841
`;
3942

packages/peregrine/lib/talons/RootComponents/Category/categoryFragments.gql.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ export const CategoryFragment = gql`
77
meta_title
88
meta_keywords
99
meta_description
10+
url_path
11+
url_key
1012
}
1113
`;
1214

packages/peregrine/lib/talons/RootComponents/Category/useCategory.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export const useCategory = props => {
4949
nextFetchPolicy: 'cache-first'
5050
});
5151
const pageSize = pageSizeData && pageSizeData.storeConfig.grid_per_page;
52+
const storeConfig = pageSizeData && pageSizeData.storeConfig;
5253

5354
const [paginationValues, paginationApi] = usePagination();
5455
const { currentPage, totalPages } = paginationValues;
@@ -222,6 +223,7 @@ export const useCategory = props => {
222223
pageControl,
223224
sortProps,
224225
pageSize,
225-
categoryNotFound
226+
categoryNotFound,
227+
storeConfig
226228
};
227229
};

packages/peregrine/lib/talons/RootComponents/Product/__tests__/useProduct.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ test('it returns the proper shape', () => {
113113
// Assert.
114114
const talonProps = log.mock.calls[0][0];
115115
const actualKeys = Object.keys(talonProps);
116-
const expectedKeys = ['error', 'loading', 'product'];
116+
const expectedKeys = ['error', 'loading', 'product', 'storeConfig'];
117117
expect(actualKeys.sort()).toEqual(expectedKeys.sort());
118118
});
119119

packages/peregrine/lib/talons/RootComponents/Product/product.gql.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export const GET_STORE_CONFIG_DATA = gql`
88
storeConfig {
99
store_code
1010
product_url_suffix
11+
product_canonical_tag
1112
}
1213
}
1314
`;

packages/peregrine/lib/talons/RootComponents/Product/useProduct.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ export const useProduct = props => {
115115
return {
116116
error,
117117
loading,
118-
product
118+
product,
119+
storeConfig: storeConfigData?.storeConfig
119120
};
120121
};

packages/venia-ui/lib/RootComponents/Category/__tests__/category.spec.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ jest.mock('@magento/peregrine/lib/talons/RootComponents/Category', () => ({
1010
jest.mock('../../../components/Head', () => ({
1111
HeadProvider: ({ children }) => <div>{children}</div>,
1212
StoreTitle: () => 'Title',
13-
Meta: () => 'Meta'
13+
Meta: () => 'Meta',
14+
Link: () => 'Link'
1415
}));
1516

1617
jest.mock('../categoryContent', () => 'CategoryContent');

packages/venia-ui/lib/RootComponents/Category/category.gql.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ export const GET_PAGE_SIZE = gql`
66
storeConfig {
77
store_code
88
grid_per_page
9+
category_url_suffix
10+
category_canonical_tag
911
}
1012
}
1113
`;

packages/venia-ui/lib/RootComponents/Category/category.js

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import React, { Fragment } from 'react';
1+
import React, { Fragment, useMemo } from 'react';
22
import { shape, string } from 'prop-types';
33
import { useCategory } from '@magento/peregrine/lib/talons/RootComponents/Category';
44
import { useStyle } from '../../classify';
55

66
import CategoryContent from './categoryContent';
77
import defaultClasses from './category.module.css';
8-
import { Meta } from '../../components/Head';
8+
import { Meta, Link } from '../../components/Head';
99
import { GET_PAGE_SIZE } from './category.gql';
1010
import ErrorView from '@magento/venia-ui/lib/components/ErrorView';
1111
import { useIntl } from 'react-intl';
@@ -34,11 +34,30 @@ const Category = props => {
3434
pageControl,
3535
sortProps,
3636
pageSize,
37-
categoryNotFound
37+
categoryNotFound,
38+
storeConfig
3839
} = talonProps;
3940

4041
const classes = useStyle(defaultClasses, props.classes);
4142

43+
// Generate canonical URL for category
44+
const canonicalUrl = useMemo(() => {
45+
if (!categoryData || !storeConfig?.category_canonical_tag) return null;
46+
47+
const category = categoryData.categories?.items?.[0];
48+
if (!category) return null;
49+
50+
// Use url_path if available, otherwise fall back to url_key
51+
const urlPath = category.url_path || category.url_key;
52+
if (!urlPath) return null;
53+
54+
const origin =
55+
typeof window !== 'undefined' ? window.location.origin : '';
56+
const suffix = storeConfig?.category_url_suffix || '';
57+
58+
return `${origin}/${urlPath}${suffix}`;
59+
}, [categoryData, storeConfig]);
60+
4261
if (!categoryData) {
4362
if (error && pageControl.currentPage === 1) {
4463
if (process.env.NODE_ENV !== 'production') {
@@ -62,6 +81,7 @@ const Category = props => {
6281
return (
6382
<Fragment>
6483
<Meta name="description" content={metaDescription} />
84+
{canonicalUrl && <Link rel="canonical" href={canonicalUrl} />}
6585
<CategoryContent
6686
categoryId={uid}
6787
classes={classes}

packages/venia-ui/lib/RootComponents/Product/__tests__/product.spec.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ jest.mock('@magento/venia-ui/lib/components/ErrorView', () => 'ErrorView');
1010
jest.mock('@magento/venia-ui/lib/components/Head', () => ({
1111
__esModule: true,
1212
StoreTitle: jest.fn(() => 'StoreTitle'),
13-
Meta: jest.fn(() => 'Meta')
13+
Meta: jest.fn(() => 'Meta'),
14+
Link: jest.fn(() => 'Link')
1415
}));
1516
jest.mock(
1617
'@magento/venia-ui/lib/components/ProductFullDetail',

0 commit comments

Comments
 (0)