@magento/venia-ui 11.7.2-alpha2 → 11.7.2-beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,7 +10,8 @@ jest.mock('@magento/peregrine/lib/talons/RootComponents/Category', () => ({
10
10
  jest.mock('../../../components/Head', () => ({
11
11
  HeadProvider: ({ children }) => <div>{children}</div>,
12
12
  StoreTitle: () => 'Title',
13
- Meta: () => 'Meta'
13
+ Meta: () => 'Meta',
14
+ Link: () => 'Link'
14
15
  }));
15
16
 
16
17
  jest.mock('../categoryContent', () => 'CategoryContent');
@@ -6,6 +6,8 @@ export const GET_PAGE_SIZE = gql`
6
6
  storeConfig {
7
7
  store_code
8
8
  grid_per_page
9
+ category_url_suffix
10
+ category_canonical_tag
9
11
  }
10
12
  }
11
13
  `;
@@ -1,11 +1,11 @@
1
- import React, { Fragment } from 'react';
1
+ import React, { Fragment, useMemo } from 'react';
2
2
  import { shape, string } from 'prop-types';
3
3
  import { useCategory } from '@magento/peregrine/lib/talons/RootComponents/Category';
4
4
  import { useStyle } from '../../classify';
5
5
 
6
6
  import CategoryContent from './categoryContent';
7
7
  import defaultClasses from './category.module.css';
8
- import { Meta } from '../../components/Head';
8
+ import { Meta, Link } from '../../components/Head';
9
9
  import { GET_PAGE_SIZE } from './category.gql';
10
10
  import ErrorView from '@magento/venia-ui/lib/components/ErrorView';
11
11
  import { useIntl } from 'react-intl';
@@ -34,11 +34,30 @@ const Category = props => {
34
34
  pageControl,
35
35
  sortProps,
36
36
  pageSize,
37
- categoryNotFound
37
+ categoryNotFound,
38
+ storeConfig
38
39
  } = talonProps;
39
40
 
40
41
  const classes = useStyle(defaultClasses, props.classes);
41
42
 
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
+
42
61
  if (!categoryData) {
43
62
  if (error && pageControl.currentPage === 1) {
44
63
  if (process.env.NODE_ENV !== 'production') {
@@ -62,6 +81,7 @@ const Category = props => {
62
81
  return (
63
82
  <Fragment>
64
83
  <Meta name="description" content={metaDescription} />
84
+ {canonicalUrl && <Link rel="canonical" href={canonicalUrl} />}
65
85
  <CategoryContent
66
86
  categoryId={uid}
67
87
  classes={classes}
@@ -10,7 +10,8 @@ jest.mock('@magento/venia-ui/lib/components/ErrorView', () => 'ErrorView');
10
10
  jest.mock('@magento/venia-ui/lib/components/Head', () => ({
11
11
  __esModule: true,
12
12
  StoreTitle: jest.fn(() => 'StoreTitle'),
13
- Meta: jest.fn(() => 'Meta')
13
+ Meta: jest.fn(() => 'Meta'),
14
+ Link: jest.fn(() => 'Link')
14
15
  }));
15
16
  jest.mock(
16
17
  '@magento/venia-ui/lib/components/ProductFullDetail',
@@ -1,10 +1,10 @@
1
- import React, { Fragment } from 'react';
1
+ import React, { Fragment, useMemo } from 'react';
2
2
  import { FormattedMessage } from 'react-intl';
3
3
  import { string } from 'prop-types';
4
4
  import { useProduct } from '@magento/peregrine/lib/talons/RootComponents/Product/useProduct';
5
5
 
6
6
  import ErrorView from '@magento/venia-ui/lib/components/ErrorView';
7
- import { StoreTitle, Meta } from '@magento/venia-ui/lib/components/Head';
7
+ import { StoreTitle, Meta, Link } from '@magento/venia-ui/lib/components/Head';
8
8
  import ProductFullDetail from '@magento/venia-ui/lib/components/ProductFullDetail';
9
9
  import mapProduct from '@magento/venia-ui/lib/util/mapProduct';
10
10
  import ProductShimmer from './product.shimmer';
@@ -23,7 +23,17 @@ const Product = props => {
23
23
  mapProduct
24
24
  });
25
25
 
26
- const { error, loading, product } = talonProps;
26
+ const { error, loading, product, storeConfig } = talonProps;
27
+
28
+ const canonicalUrl = useMemo(() => {
29
+ if (!product || !storeConfig?.product_canonical_tag) return null;
30
+
31
+ const origin =
32
+ typeof window !== 'undefined' ? window.location.origin : '';
33
+ const suffix = storeConfig?.product_url_suffix || '';
34
+
35
+ return `${origin}/${product.url_key}${suffix}`;
36
+ }, [product, storeConfig]);
27
37
 
28
38
  if (loading && !product)
29
39
  return <ProductShimmer productType={productType} />;
@@ -45,6 +55,7 @@ const Product = props => {
45
55
  <Fragment>
46
56
  <StoreTitle>{product.name}</StoreTitle>
47
57
  <Meta name="description" content={product.meta_description} />
58
+ {canonicalUrl && <Link rel="canonical" href={canonicalUrl} />}
48
59
  <ProductFullDetail product={product} />
49
60
  </Fragment>
50
61
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magento/venia-ui",
3
- "version": "11.7.2-alpha2",
3
+ "version": "11.7.2-beta1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -80,7 +80,7 @@
80
80
  "peerDependencies": {
81
81
  "@apollo/client": "~3.5.0",
82
82
  "@magento/babel-preset-peregrine": "~1.3.3",
83
- "@magento/peregrine": "15.7.2-alpha2",
83
+ "@magento/peregrine": "15.7.2-beta1",
84
84
  "@magento/pwa-buildpack": "~11.5.5",
85
85
  "apollo-cache-persist": "~0.1.1",
86
86
  "braintree-web-drop-in": "~1.43.0",