@shopify/create-hydrogen 0.1.3 → 0.15.0

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.
Files changed (95) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/bin/run.cmd +3 -0
  3. package/bin/run.js +5 -0
  4. package/dist/commands/init.js +76390 -0
  5. package/dist/commands/init.js.map +1 -0
  6. package/dist/index.js +21 -0
  7. package/dist/index.js.map +1 -0
  8. package/package.json +56 -14
  9. package/templates/template-hydrogen/.devcontainer/devcontainer.json +18 -0
  10. package/templates/template-hydrogen/.eslintrc.js +3 -0
  11. package/templates/template-hydrogen/.gitignore +7 -0
  12. package/templates/template-hydrogen/.stackblitzrc +4 -0
  13. package/{template-hydrogen → templates/template-hydrogen}/.stylelintrc.js +1 -1
  14. package/templates/template-hydrogen/.vscode/extensions.json +8 -0
  15. package/templates/template-hydrogen/Dockerfile +15 -0
  16. package/{template-hydrogen → templates/template-hydrogen}/README.md +11 -2
  17. package/{template-hydrogen → templates/template-hydrogen}/_gitignore +0 -0
  18. package/templates/template-hydrogen/index.html +20 -0
  19. package/{template-hydrogen → templates/template-hydrogen}/package.json +20 -15
  20. package/{template-hydrogen → templates/template-hydrogen}/postcss.config.js +0 -0
  21. package/{template-hydrogen/src → templates/template-hydrogen/public}/favicon.svg +0 -0
  22. package/{template-hydrogen → templates/template-hydrogen}/server.js +4 -2
  23. package/{template-hydrogen → templates/template-hydrogen}/shopify.config.js +1 -2
  24. package/templates/template-hydrogen/src/App.client.jsx +8 -0
  25. package/templates/template-hydrogen/src/App.server.jsx +27 -0
  26. package/templates/template-hydrogen/src/components/Button.client.jsx +65 -0
  27. package/templates/template-hydrogen/src/components/Cart.client.jsx +265 -0
  28. package/templates/template-hydrogen/src/components/CartIcon.jsx +33 -0
  29. package/templates/template-hydrogen/src/components/CartIconWithItems.client.jsx +28 -0
  30. package/templates/template-hydrogen/src/components/CartProvider.client.jsx +35 -0
  31. package/templates/template-hydrogen/src/components/CartToggle.client.jsx +30 -0
  32. package/templates/template-hydrogen/src/components/CartUIProvider.client.jsx +45 -0
  33. package/templates/template-hydrogen/src/components/CountrySelector.client.jsx +116 -0
  34. package/templates/template-hydrogen/src/components/DefaultSeo.server.jsx +35 -0
  35. package/templates/template-hydrogen/src/components/FeaturedCollection.jsx +26 -0
  36. package/templates/template-hydrogen/src/components/Footer.server.jsx +103 -0
  37. package/templates/template-hydrogen/src/components/Gallery.client.jsx +65 -0
  38. package/templates/template-hydrogen/src/components/Header.client.jsx +62 -0
  39. package/templates/template-hydrogen/src/components/Layout.server.jsx +87 -0
  40. package/templates/template-hydrogen/src/components/LoadMoreProducts.client.jsx +56 -0
  41. package/templates/template-hydrogen/src/components/LoadingFallback.jsx +26 -0
  42. package/templates/template-hydrogen/src/components/MobileCountrySelector.client.jsx +64 -0
  43. package/templates/template-hydrogen/src/components/MobileNavigation.client.jsx +98 -0
  44. package/templates/template-hydrogen/src/components/MoneyCompareAtPrice.client.jsx +14 -0
  45. package/templates/template-hydrogen/src/components/MoneyPrice.client.jsx +15 -0
  46. package/templates/template-hydrogen/src/components/Navigation.client.jsx +23 -0
  47. package/templates/template-hydrogen/src/components/NotFound.server.jsx +93 -0
  48. package/templates/template-hydrogen/src/components/OpenIcon.jsx +33 -0
  49. package/templates/template-hydrogen/src/components/ProductCard.jsx +50 -0
  50. package/templates/template-hydrogen/src/components/ProductDetails.client.jsx +242 -0
  51. package/{template-hydrogen → templates/template-hydrogen}/src/components/ProductOptions.client.jsx +7 -4
  52. package/templates/template-hydrogen/src/components/Welcome.server.jsx +188 -0
  53. package/templates/template-hydrogen/src/entry-client.jsx +7 -0
  54. package/templates/template-hydrogen/src/entry-server.jsx +6 -0
  55. package/{template-hydrogen → templates/template-hydrogen}/src/index.css +31 -0
  56. package/templates/template-hydrogen/src/pages/collections/[handle].server.jsx +105 -0
  57. package/templates/template-hydrogen/src/pages/index.server.jsx +237 -0
  58. package/{template-hydrogen → templates/template-hydrogen}/src/pages/pages/[handle].server.jsx +14 -5
  59. package/templates/template-hydrogen/src/pages/products/[handle].server.jsx +69 -0
  60. package/templates/template-hydrogen/src/pages/redirect.server.jsx +4 -0
  61. package/templates/template-hydrogen/src/pages/robots.txt.server.js +10 -0
  62. package/{template-hydrogen → templates/template-hydrogen}/src/pages/sitemap.xml.server.jsx +2 -2
  63. package/templates/template-hydrogen/tailwind.config.js +26 -0
  64. package/{template-hydrogen → templates/template-hydrogen}/vite.config.js +1 -0
  65. package/{template-hydrogen → templates/template-hydrogen}/worker.js +1 -0
  66. package/index.js +0 -201
  67. package/scripts/tmp-copy-template-from-dev.js +0 -21
  68. package/scripts/utils.js +0 -29
  69. package/template-hydrogen/.eslintrc.js +0 -41
  70. package/template-hydrogen/.vscode/extensions.json +0 -3
  71. package/template-hydrogen/Dockerfile +0 -15
  72. package/template-hydrogen/index.html +0 -14
  73. package/template-hydrogen/src/App.server.jsx +0 -42
  74. package/template-hydrogen/src/components/Cart.client.jsx +0 -288
  75. package/template-hydrogen/src/components/CartProvider.client.jsx +0 -15
  76. package/template-hydrogen/src/components/DefaultSeo.server.jsx +0 -22
  77. package/template-hydrogen/src/components/Footer.jsx +0 -12
  78. package/template-hydrogen/src/components/Gallery.client.jsx +0 -36
  79. package/template-hydrogen/src/components/Header.client.jsx +0 -46
  80. package/template-hydrogen/src/components/HightlightedProduct.client.jsx +0 -54
  81. package/template-hydrogen/src/components/Layout.client.jsx +0 -61
  82. package/template-hydrogen/src/components/MediaPlaceholder.jsx +0 -21
  83. package/template-hydrogen/src/components/NotFound.server.jsx +0 -104
  84. package/template-hydrogen/src/components/ProductCard.client.jsx +0 -39
  85. package/template-hydrogen/src/components/ProductDetails.client.jsx +0 -184
  86. package/template-hydrogen/src/components/Seo.client.jsx +0 -75
  87. package/template-hydrogen/src/entry-client.jsx +0 -12
  88. package/template-hydrogen/src/entry-server.jsx +0 -7
  89. package/template-hydrogen/src/pages/Index.server.jsx +0 -197
  90. package/template-hydrogen/src/pages/blogs/[handle]/[articleHandle].server.jsx +0 -49
  91. package/template-hydrogen/src/pages/blogs/[handle].server.jsx +0 -76
  92. package/template-hydrogen/src/pages/collections/[handle].server.jsx +0 -69
  93. package/template-hydrogen/src/pages/products/[handle].server.jsx +0 -60
  94. package/template-hydrogen/src/pages/search.server.jsx +0 -107
  95. package/template-hydrogen/tailwind.config.js +0 -9
@@ -1,22 +0,0 @@
1
- import {useShopQuery} from '@shopify/hydrogen';
2
- import gql from 'graphql-tag';
3
-
4
- import Seo from './Seo.client';
5
-
6
- export default function SeoServer() {
7
- const {
8
- data: {
9
- shop: {name: shopName},
10
- },
11
- } = useShopQuery({query: QUERY});
12
-
13
- return <Seo shopName={shopName} />;
14
- }
15
-
16
- const QUERY = gql`
17
- query shopName {
18
- shop {
19
- name
20
- }
21
- }
22
- `;
@@ -1,12 +0,0 @@
1
- export default function Footer() {
2
- return (
3
- <footer
4
- role="contentinfo"
5
- className="flex items-center justify-between p-4 md:py-8 md:px-8 max-w-7xl mx-auto"
6
- >
7
- <p className="text-gray-600">© 2021 Shopify</p>
8
- <div>{/* TODO: Payment icons */}</div>
9
- <p className="text-gray-400">Powered by Shopify</p>
10
- </footer>
11
- );
12
- }
@@ -1,36 +0,0 @@
1
- import {useProduct, MediaFile} from '@shopify/hydrogen/client';
2
-
3
- export default function Gallery() {
4
- return (
5
- <>
6
- <GalleryPreview />
7
- </>
8
- );
9
- }
10
-
11
- function GalleryPreview() {
12
- const {media} = useProduct();
13
-
14
- if (!media.length) {
15
- return null;
16
- }
17
-
18
- return (
19
- <ul className="grid lg:grid-cols-2 gap-10">
20
- {media.map((med) => {
21
- return (
22
- <li key={med.id} className="relative">
23
- <MediaFile
24
- className="w-full bg-white rounded-md object-cover"
25
- media={med}
26
- options={{
27
- height: '1000',
28
- crop: 'center',
29
- }}
30
- />
31
- </li>
32
- );
33
- })}
34
- </ul>
35
- );
36
- }
@@ -1,46 +0,0 @@
1
- import {Link, CartToggle} from '@shopify/hydrogen/client';
2
-
3
- import {CartIcon} from './Cart.client';
4
-
5
- export default function Header() {
6
- return (
7
- <header
8
- className="z-10 relative flex items-center justify-between pt-3 md:pt-12 md:pb-4 md:px-8 max-w-7xl mx-auto"
9
- role="banner"
10
- >
11
- <nav>
12
- <ul className="hidden md:flex items-center justify-center space-x-6 font-medium relative">
13
- <li>
14
- <Link to="/">Home</Link>
15
- </li>
16
- <li>
17
- <Link to="/" className="flex items-center justify-center">
18
- Collections
19
- <svg
20
- xmlns="http://www.w3.org/2000/svg"
21
- className="h-5 w-5"
22
- viewBox="0 0 20 20"
23
- fill="currentColor"
24
- >
25
- <path
26
- fillRule="evenodd"
27
- d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
28
- clipRule="evenodd"
29
- />
30
- </svg>
31
- </Link>
32
- </li>
33
- </ul>
34
- </nav>
35
- <Link
36
- className="text-center font-bold uppercase text-2xl tracking-widest absolute left-1/2 transform -translate-x-1/2"
37
- to="/"
38
- >
39
- My Shop
40
- </Link>
41
- <CartToggle className="h-12 w-12 p-2 mr-2 md:mr-0 md:h-7 md:w-7 md:p-0">
42
- <CartIcon />
43
- </CartToggle>
44
- </header>
45
- );
46
- }
@@ -1,54 +0,0 @@
1
- import {
2
- ProductProvider,
3
- SelectedVariantImage,
4
- ProductTitle,
5
- SelectedVariantPrice,
6
- SelectedVariantAddToCartButton,
7
- Link,
8
- } from '@shopify/hydrogen/client';
9
-
10
- import ProductOptions from './ProductOptions.client';
11
-
12
- export default function HighlightedProduct({product}) {
13
- if (!product) {
14
- return null;
15
- }
16
-
17
- return (
18
- <ProductProvider
19
- product={product}
20
- initialVariantId={product.variants.edges[0].node.id}
21
- >
22
- <SelectedVariantImage className="rounded-md bg-gray-100 w-full md:min-h-96 md:w-96 object-cover" />
23
- <div className="pt-4 md:pl-10 w-full flex flex-col">
24
- <Link to={`/products/${product.handle}`}>
25
- <ProductTitle className="text-gray-900 text-xl md:text-3xl font-medium" />
26
- </Link>
27
- <div className="my-2 md:my-4 md:mb-16">
28
- <SelectedVariantPrice className="font-semibold md:font-medium text-gray-900 md:text-xl">
29
- {({currencyCode, amount, currencyNarrowSymbol}) => {
30
- return (
31
- <span>{`${currencyCode} ${currencyNarrowSymbol}${amount}`}</span>
32
- );
33
- }}
34
- </SelectedVariantPrice>
35
- <SelectedVariantPrice
36
- priceType="compareAt"
37
- className="text-gray-400 line-through md:text-xl"
38
- >
39
- {({amount, currencyNarrowSymbol}) => {
40
- return <span>{`${currencyNarrowSymbol}${amount}`}</span>;
41
- }}
42
- </SelectedVariantPrice>
43
- </div>
44
- <ProductOptions />
45
- <SelectedVariantAddToCartButton className="rounded-md bg-gray-900 text-white text-center p-4 text-sm uppercase w-full mt-4 mb-2">
46
- Add to bag
47
- </SelectedVariantAddToCartButton>
48
- <p className="text-gray-500 text-xs text-center">
49
- Free shipping and 30 day returns
50
- </p>
51
- </div>
52
- </ProductProvider>
53
- );
54
- }
@@ -1,61 +0,0 @@
1
- import {
2
- CartUIProvider,
3
- CartContainer,
4
- useCartUI,
5
- } from '@shopify/hydrogen/client';
6
-
7
- import Header from './Header.client';
8
- import Footer from './Footer';
9
- import Cart from './Cart.client';
10
-
11
- export default function Layout({children}) {
12
- return (
13
- <CartUIProvider>
14
- <InnerLayout>{children}</InnerLayout>
15
- </CartUIProvider>
16
- );
17
- }
18
-
19
- function InnerLayout({children}) {
20
- const {isCartOpen, closeCart} = useCartUI();
21
-
22
- return (
23
- <>
24
- <div className="absolute top-0 left-0">
25
- <a
26
- href="#mainContent"
27
- className="p-4 focus:block sr-only focus:not-sr-only"
28
- >
29
- Skip to content
30
- </a>
31
- </div>
32
- <div className="min-h-screen max-w-screen text-gray-700">
33
- <Header />
34
- {/* eslint-disable-next-line @shopify/jsx-prefer-fragment-wrappers */}
35
- <div>
36
- <div
37
- className={`z-50 fixed top-0 bottom-0 left-0 right-0 bg-black transition-opacity duration-400 ${
38
- isCartOpen ? 'opacity-20' : 'opacity-0 pointer-events-none'
39
- }`}
40
- onClick={isCartOpen ? closeCart : null}
41
- />
42
- <CartContainer
43
- id="cart"
44
- className={`pointer-events-none z-50 fixed right-0 top-0 bottom-0 md:p-5 flex flex-col w-full max-w-md min-w-sm transition-transform duration-500 transform-gpu ${
45
- isCartOpen ? 'right-0' : 'translate-x-full'
46
- }`}
47
- >
48
- <Cart />
49
- </CartContainer>
50
- </div>
51
- <main
52
- id="mainContent"
53
- className="mx-auto max-w-7xl p-4 md:py-5 md:px-8"
54
- >
55
- {children}
56
- </main>
57
- <Footer />
58
- </div>
59
- </>
60
- );
61
- }
@@ -1,21 +0,0 @@
1
- export default function MediaPlaceholder({text}) {
2
- return (
3
- <div className="text-gray-500 h-full w-full p-4 bg-gray-200 flex flex-col items-center justify-center space-y-4">
4
- <svg
5
- xmlns="http://www.w3.org/2000/svg"
6
- className="h-10 w-10"
7
- fill="none"
8
- viewBox="0 0 24 24"
9
- stroke="currentColor"
10
- >
11
- <path
12
- strokeLinecap="round"
13
- strokeLinejoin="round"
14
- strokeWidth={2}
15
- d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
16
- />
17
- </svg>
18
- {text && <p className="text-sm max-w-xs text-center">{text}</p>}
19
- </div>
20
- );
21
- }
@@ -1,104 +0,0 @@
1
- import {useShopQuery, MediaFile} from '@shopify/hydrogen';
2
- import {Link} from '@shopify/hydrogen/client';
3
- import gql from 'graphql-tag';
4
-
5
- import Layout from './Layout.client';
6
- import ProductCard from './ProductCard.client';
7
-
8
- export default function NotFound() {
9
- const {data} = useShopQuery({query: QUERY});
10
- const {products} = data;
11
-
12
- return (
13
- <Layout>
14
- <div className="text-center py-10 md:py-40 max-w-2xl mx-auto space-y-6">
15
- <h1 className="text-4xl font-extrabold leading-tight">
16
- We’ve lost this page
17
- </h1>
18
- <p className="text-xl text-gray-500">
19
- We couldn’t find the page you’re looking for. Try checking the URL or
20
- heading back to the home page.
21
- </p>
22
- <Link
23
- className="block max-w-md mx-auto text-white p-3 rounded mb-8 uppercase text-lg bg-black"
24
- to="/"
25
- >
26
- Take me to the home page
27
- </Link>
28
- </div>
29
-
30
- <hr className="border-gray-300" />
31
-
32
- <h2 className="my-8 text-2xl text-gray-700 font-bold">
33
- Products you might like
34
- </h2>
35
-
36
- <ul className="grid lg:grid-cols-3 gap-6 my-4">
37
- {products.edges.map((edge) => (
38
- <li key={edge.node.id}>
39
- <ProductCard product={edge.node} />
40
- </li>
41
- ))}
42
- </ul>
43
- </Layout>
44
- );
45
- }
46
-
47
- const QUERY = gql`
48
- fragment NotFoundProductDetails on Product {
49
- id
50
- title
51
- handle
52
- priceRange {
53
- maxVariantPrice {
54
- amount
55
- currencyCode
56
- }
57
- minVariantPrice {
58
- amount
59
- currencyCode
60
- }
61
- }
62
- variants(first: 1) {
63
- edges {
64
- node {
65
- priceV2 {
66
- currencyCode
67
- amount
68
- }
69
- compareAtPriceV2 {
70
- currencyCode
71
- amount
72
- }
73
- image {
74
- ...ImageFragment
75
- }
76
- selectedOptions {
77
- name
78
- value
79
- }
80
- }
81
- }
82
- }
83
- media(first: 1) {
84
- edges {
85
- node {
86
- ...MediaFileFragment
87
- }
88
- }
89
- }
90
- }
91
-
92
- query Products {
93
- products(first: 3) {
94
- edges {
95
- node {
96
- id
97
- ...NotFoundProductDetails
98
- }
99
- }
100
- }
101
- }
102
-
103
- ${MediaFile.Fragment}
104
- `;
@@ -1,39 +0,0 @@
1
- import {
2
- Link,
3
- ProductProvider,
4
- ProductTitle,
5
- SelectedVariantImage,
6
- SelectedVariantPrice,
7
- } from '@shopify/hydrogen/client';
8
-
9
- export default function ProductCard({product}) {
10
- const firstVariant = product?.variants?.edges[0]?.node;
11
-
12
- if (!product) return null;
13
-
14
- return (
15
- <ProductProvider product={product} initialVariantId={firstVariant.id}>
16
- <Link to={`/products/${product.handle}`}>
17
- <SelectedVariantImage className="rounded-md bg-gray-100 h-80 w-96 mb-2" />
18
- <ProductTitle className="text-gray-900 font-medium" />
19
- </Link>
20
- <div className="flex items-center">
21
- <SelectedVariantPrice className="text-gray-900">
22
- {({currencyCode, amount, currencyNarrowSymbol}) => {
23
- return (
24
- <span>{`${currencyCode} ${currencyNarrowSymbol}${amount}`}</span>
25
- );
26
- }}
27
- </SelectedVariantPrice>
28
- <SelectedVariantPrice
29
- priceType="compareAt"
30
- className="text-gray-400 line-through"
31
- >
32
- {({amount, currencyNarrowSymbol}) => {
33
- return <span>{`${currencyNarrowSymbol}${amount}`}</span>;
34
- }}
35
- </SelectedVariantPrice>
36
- </div>
37
- </ProductProvider>
38
- );
39
- }
@@ -1,184 +0,0 @@
1
- import {Product} from '@shopify/hydrogen/client';
2
-
3
- import Layout from './Layout.client';
4
- import ProductOptions from './ProductOptions.client';
5
- import Gallery from './Gallery.client';
6
- import Seo from './Seo.client';
7
-
8
- export default function ProductDetails({data}) {
9
- return (
10
- <Layout>
11
- <Seo product={data.product} />
12
- <Product
13
- product={data.product}
14
- initialVariantId={data.product.variants.edges[0].node.id}
15
- >
16
- <div className="py-4 md:grid md:grid-cols-2 lg:grid-cols-3 gap-12">
17
- <div className="md:hidden pb-4 flex justify-between items-top">
18
- <Product.Title as="h1" className="font-bold text-2xl" />
19
- <div className="flex items-center gap-1">
20
- <Product.SelectedVariant.Price className="text-xl" />
21
- <Product.SelectedVariant.Price
22
- priceType="compareAt"
23
- className="line-through text-gray-400"
24
- />
25
- </div>
26
- </div>
27
-
28
- <section className="lg:col-span-2 grid gap-10" aria-label="Gallery">
29
- <Gallery />
30
- </section>
31
-
32
- <section
33
- className="my-4 md:my-0 max-w-md flex flex-col gap-6"
34
- aria-label="Product details"
35
- >
36
- {/* eslint-disable-next-line @shopify/jsx-prefer-fragment-wrappers */}
37
- <div>
38
- <Product.Title className="text-gray-900 text-3xl font-medium" />
39
-
40
- <Product.Metafield
41
- namespace="reviews"
42
- keyName="rating"
43
- className="text-yellow-500 text-lg"
44
- />
45
-
46
- <div className="my-4 gap-1 hidden md:block">
47
- <Product.SelectedVariant.Price className="font-semibold text-gray-900 text-2xl">
48
- {({currencyCode, amount, currencyNarrowSymbol}) => {
49
- return (
50
- <span>{`${currencyCode} ${currencyNarrowSymbol}${amount}`}</span>
51
- );
52
- }}
53
- </Product.SelectedVariant.Price>
54
- <Product.SelectedVariant.Price
55
- priceType="compareAt"
56
- className="text-gray-400 line-through text-xl"
57
- >
58
- {({amount, currencyNarrowSymbol}) => {
59
- return <span>{`${currencyNarrowSymbol}${amount}`}</span>;
60
- }}
61
- </Product.SelectedVariant.Price>
62
-
63
- <Product.SelectedVariant.UnitPrice className="text-gray-900 text-base">
64
- {({
65
- currencyCode,
66
- amount,
67
- currencyNarrowSymbol,
68
- referenceUnit,
69
- }) => {
70
- return (
71
- <span>{`${currencyCode} ${currencyNarrowSymbol}${amount}/${referenceUnit}`}</span>
72
- );
73
- }}
74
- </Product.SelectedVariant.UnitPrice>
75
-
76
- <Product.SelectedVariant.Metafield
77
- namespace="my_fields"
78
- keyName="no_tax"
79
- >
80
- {({value}) => {
81
- return value ? <span>We pay the tax!</span> : null;
82
- }}
83
- </Product.SelectedVariant.Metafield>
84
- </div>
85
-
86
- <ProductOptions />
87
-
88
- <div className="my-8 space-y-2">
89
- <Product.SelectedVariant.AddToCartButton className="rounded-md bg-gray-900 text-white text-center p-4 text-sm uppercase w-full">
90
- Add to bag
91
- </Product.SelectedVariant.AddToCartButton>
92
- <Product.SelectedVariant.BuyNowButton className="rounded-md bg-white border border-black text-center p-4 text-sm uppercase w-full">
93
- Buy it now
94
- </Product.SelectedVariant.BuyNowButton>
95
- <Product.SelectedVariant.ShopPayButton className="flex justify-center w-full" />
96
- </div>
97
-
98
- <ul className="flex gap-2">
99
- <Product.Metafield
100
- namespace="my_fields"
101
- keyName="made_in_canada"
102
- >
103
- {({value}) => {
104
- return value ? (
105
- <li className="uppercase text-xs bg-red-500 text-white text-center font-semibold rounded-full h-20 w-20 flex items-center justify-center p-3">
106
- Made in Canada
107
- </li>
108
- ) : null;
109
- }}
110
- </Product.Metafield>
111
- <Product.Metafield namespace="my_fields" keyName="flex">
112
- {({value}) => {
113
- return (
114
- <li className="uppercase bg-gray-600 text-white text-center font-semibold rounded-full h-20 w-20 flex flex-col items-center justify-center p-3">
115
- <span className="text-xs">Flex</span>
116
- <span className="text-4xl">{value}</span>
117
- </li>
118
- );
119
- }}
120
- </Product.Metafield>
121
- </ul>
122
-
123
- <Product.Description className="prose" />
124
-
125
- <section className="mt-4">
126
- <h3 className="text-lg font-semibold">Care Guide</h3>
127
- <Product.Metafield
128
- namespace="descriptors"
129
- keyName="care_guide"
130
- />
131
- </section>
132
-
133
- <section className="mt-4">
134
- <h3 className="text-lg font-semibold">Specs</h3>
135
- <ul>
136
- <li>
137
- Weight:{' '}
138
- <Product.Metafield
139
- namespace="my_fields"
140
- keyName="product_weight"
141
- />
142
- </li>
143
- <li>
144
- Length:{' '}
145
- <Product.Metafield namespace="my_fields" keyName="length" />
146
- </li>
147
- <li>
148
- Width:{' '}
149
- <Product.Metafield namespace="my_fields" keyName="width" />
150
- </li>
151
- <li>
152
- Manufactured on:{' '}
153
- <Product.Metafield
154
- namespace="my_fields"
155
- keyName="manufacture_date"
156
- />
157
- </li>
158
- <li>
159
- Manufactured by:{' '}
160
- <Product.Metafield
161
- namespace="my_fields"
162
- keyName="manufacturer_url"
163
- >
164
- {({value}) => {
165
- return (
166
- <a href={value} className="inline-block">
167
- <Product.Metafield
168
- namespace="my_fields"
169
- keyName="manufacturer_name"
170
- />
171
- </a>
172
- );
173
- }}
174
- </Product.Metafield>
175
- </li>
176
- </ul>
177
- </section>
178
- </div>
179
- </section>
180
- </div>
181
- </Product>
182
- </Layout>
183
- );
184
- }
@@ -1,75 +0,0 @@
1
- import {useShop, Helmet} from '@shopify/hydrogen/client';
2
-
3
- export default function Seo({shopName, product}) {
4
- const {locale} = useShop();
5
- const lang = locale.split(/[-_]/)[0];
6
-
7
- if (product) {
8
- const variant = product.variants.edges[0].node;
9
- const price = variant.priceV2;
10
- const image = product.images.edges[0]?.node;
11
- const title = product.seo?.title ?? product.title;
12
- const description = product.seo?.description ?? product.description;
13
-
14
- /* TODO: Find a way to get the full URL */
15
- const url = typeof window === 'undefined' ? '' : window.location.href;
16
-
17
- return (
18
- <Helmet>
19
- <title>{title}</title>
20
- <meta name="description" content={description} />
21
- {url && <meta property="og:url" content={url} />}
22
- <meta property="og:title" content={title} />
23
- <meta property="og:type" content="product" />
24
- <meta property="og:description" content={description} />
25
- <meta property="og:price:amount" content={price.amount} />
26
- <meta property="og:price:currency" content={price.currencyCode} />
27
-
28
- {image && <meta property="og:image" content={image.originalSrc} />}
29
- {image && (
30
- <meta property="og:image:secure_url" content={image.originalSrc} />
31
- )}
32
-
33
- <meta name="twitter:card" content="summary_large_image" />
34
- <meta name="twitter:title" content={title} />
35
- <meta name="twitter:description" content={description} />
36
-
37
- <script type="application/ld+json">{`
38
- {
39
- "@context": "https://schema.org/",
40
- "@type": "Product",
41
- "name": "${product.title}",
42
- "image": [
43
- ${image ? `"${image.originalSrc}"` : ''}
44
- ],
45
- "description": "${description}",
46
- "brand": {
47
- "@type": "Brand",
48
- "name": "${product.vendor}"
49
- },
50
- "offers": {
51
- "@type": "Offer",
52
- "url": "${url}",
53
- "priceCurrency": "${price.currencyCode}",
54
- "price": "${price.amount}",
55
- "availability": "https://schema.org/${
56
- variant.availableForSale ? 'InStock' : 'OutOfStock'
57
- }"
58
- }
59
- }
60
- `}</script>
61
- </Helmet>
62
- );
63
- }
64
-
65
- /**
66
- * Return a global SEO helper if no other props were passed.
67
- * Useful for placing in the "main" <App> container.
68
- */
69
- return (
70
- <Helmet defaultTitle={shopName} titleTemplate={`%s - ${shopName}`}>
71
- <html lang={lang} />
72
- <meta property="og:site_name" content={shopName} />
73
- </Helmet>
74
- );
75
- }
@@ -1,12 +0,0 @@
1
- import renderHydrogen from '@shopify/hydrogen/entry-client';
2
- import {ShopifyProvider} from '@shopify/hydrogen/client';
3
-
4
- import shopifyConfig from '../shopify.config';
5
-
6
- function ClientApp({children}) {
7
- return (
8
- <ShopifyProvider shopifyConfig={shopifyConfig}>{children}</ShopifyProvider>
9
- );
10
- }
11
-
12
- export default renderHydrogen(ClientApp);
@@ -1,7 +0,0 @@
1
- import renderHydrogen from '@shopify/hydrogen/entry-server';
2
-
3
- import App from './App.server';
4
-
5
- export default renderHydrogen(App, () => {
6
- // Custom hook
7
- });