@shopify/create-hydrogen 1.0.9 → 2.0.2
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.
- package/CHANGELOG.md +26 -0
- package/dist/commands/init.js +133 -62
- package/dist/commands/init.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +12 -8
- package/templates/template-hydrogen-default/.devcontainer/devcontainer.json +0 -18
- package/templates/template-hydrogen-default/.eslintrc.js +0 -3
- package/templates/template-hydrogen-default/.gitignore +0 -7
- package/templates/template-hydrogen-default/.stylelintrc.js +0 -17
- package/templates/template-hydrogen-default/.vscode/extensions.json +0 -8
- package/templates/template-hydrogen-default/README.md +0 -40
- package/templates/template-hydrogen-default/_gitignore +0 -80
- package/templates/template-hydrogen-default/index.html +0 -20
- package/templates/template-hydrogen-default/package.json.liquid +0 -48
- package/templates/template-hydrogen-default/postcss.config.js +0 -6
- package/templates/template-hydrogen-default/public/favicon.ico +0 -0
- package/templates/template-hydrogen-default/shopify.config.js +0 -5
- package/templates/template-hydrogen-default/src/App.server.jsx +0 -27
- package/templates/template-hydrogen-default/src/components/Button.client.jsx +0 -65
- package/templates/template-hydrogen-default/src/components/Cart.client.jsx +0 -265
- package/templates/template-hydrogen-default/src/components/CartIcon.jsx +0 -33
- package/templates/template-hydrogen-default/src/components/CartIconWithItems.client.jsx +0 -28
- package/templates/template-hydrogen-default/src/components/CartProvider.client.jsx +0 -35
- package/templates/template-hydrogen-default/src/components/CartToggle.client.jsx +0 -30
- package/templates/template-hydrogen-default/src/components/CartUIProvider.client.jsx +0 -45
- package/templates/template-hydrogen-default/src/components/CountrySelector.client.jsx +0 -116
- package/templates/template-hydrogen-default/src/components/DefaultSeo.server.jsx +0 -36
- package/templates/template-hydrogen-default/src/components/FeaturedCollection.jsx +0 -26
- package/templates/template-hydrogen-default/src/components/Footer.server.jsx +0 -103
- package/templates/template-hydrogen-default/src/components/Gallery.client.jsx +0 -66
- package/templates/template-hydrogen-default/src/components/Header.client.jsx +0 -62
- package/templates/template-hydrogen-default/src/components/Layout.server.jsx +0 -86
- package/templates/template-hydrogen-default/src/components/LoadMoreProducts.client.jsx +0 -56
- package/templates/template-hydrogen-default/src/components/LoadingFallback.jsx +0 -26
- package/templates/template-hydrogen-default/src/components/MobileCountrySelector.client.jsx +0 -64
- package/templates/template-hydrogen-default/src/components/MobileNavigation.client.jsx +0 -98
- package/templates/template-hydrogen-default/src/components/MoneyCompareAtPrice.client.jsx +0 -14
- package/templates/template-hydrogen-default/src/components/MoneyPrice.client.jsx +0 -15
- package/templates/template-hydrogen-default/src/components/Navigation.client.jsx +0 -23
- package/templates/template-hydrogen-default/src/components/NotFound.server.jsx +0 -93
- package/templates/template-hydrogen-default/src/components/OpenIcon.jsx +0 -33
- package/templates/template-hydrogen-default/src/components/ProductCard.jsx +0 -50
- package/templates/template-hydrogen-default/src/components/ProductDetails.client.jsx +0 -233
- package/templates/template-hydrogen-default/src/components/ProductOptions.client.jsx +0 -49
- package/templates/template-hydrogen-default/src/components/Welcome.server.jsx +0 -188
- package/templates/template-hydrogen-default/src/index.css +0 -68
- package/templates/template-hydrogen-default/src/pages/collections/[handle].server.jsx +0 -105
- package/templates/template-hydrogen-default/src/pages/index.server.jsx +0 -241
- package/templates/template-hydrogen-default/src/pages/pages/[handle].server.jsx +0 -37
- package/templates/template-hydrogen-default/src/pages/products/[handle].server.jsx +0 -66
- package/templates/template-hydrogen-default/src/pages/redirect.server.jsx +0 -4
- package/templates/template-hydrogen-default/src/pages/robots.txt.server.js +0 -40
- package/templates/template-hydrogen-default/src/pages/sitemap.xml.server.jsx +0 -151
- package/templates/template-hydrogen-default/src/routes/collections/[handle].server.jsx +0 -105
- package/templates/template-hydrogen-default/src/routes/index.server.jsx +0 -241
- package/templates/template-hydrogen-default/src/routes/pages/[handle].server.jsx +0 -37
- package/templates/template-hydrogen-default/src/routes/products/[handle].server.jsx +0 -66
- package/templates/template-hydrogen-default/src/routes/redirect.server.jsx +0 -4
- package/templates/template-hydrogen-default/src/routes/robots.txt.server.js +0 -40
- package/templates/template-hydrogen-default/src/routes/sitemap.xml.server.jsx +0 -151
- package/templates/template-hydrogen-default/tailwind.config.js +0 -26
- package/templates/template-hydrogen-default/vite.config.js +0 -10
- package/templates/template-hydrogen-minimal/README.md +0 -8
- package/templates/template-hydrogen-minimal/package.json +0 -14
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
import {useShopQuery, flattenConnection, Link} from '@shopify/hydrogen';
|
|
2
|
-
import gql from 'graphql-tag';
|
|
3
|
-
import {Suspense} from 'react';
|
|
4
|
-
|
|
5
|
-
function ExternalIcon() {
|
|
6
|
-
return (
|
|
7
|
-
<svg
|
|
8
|
-
className="ml-3"
|
|
9
|
-
width="15"
|
|
10
|
-
height="14"
|
|
11
|
-
viewBox="0 0 15 14"
|
|
12
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
13
|
-
fill="currentColor"
|
|
14
|
-
>
|
|
15
|
-
<path d="M8.11963 0.000976562C7.56734 0.000976562 7.11963 0.448692 7.11963 1.00098C7.11963 1.55326 7.56734 2.00098 8.11963 2.00098H10.7054L4.41252 8.29387C4.022 8.68439 4.022 9.31756 4.41252 9.70808C4.80305 10.0986 5.43621 10.0986 5.82674 9.70808L12.1196 3.41519V6.00098C12.1196 6.55326 12.5673 7.00098 13.1196 7.00098C13.6719 7.00098 14.1196 6.55326 14.1196 6.00098V1.00098C14.1196 0.448692 13.6719 0.000976562 13.1196 0.000976562H8.11963Z" />
|
|
16
|
-
<path d="M2.11963 2.00098C1.01506 2.00098 0.119629 2.89641 0.119629 4.00098V12.001C0.119629 13.1055 1.01506 14.001 2.11963 14.001H10.1196C11.2242 14.001 12.1196 13.1055 12.1196 12.001V9.00098C12.1196 8.44869 11.6719 8.00098 11.1196 8.00098C10.5673 8.00098 10.1196 8.44869 10.1196 9.00098V12.001H2.11963V4.00098L5.11963 4.00098C5.67191 4.00098 6.11963 3.55326 6.11963 3.00098C6.11963 2.44869 5.67191 2.00098 5.11963 2.00098H2.11963Z" />
|
|
17
|
-
</svg>
|
|
18
|
-
);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function DocsButton({url, label}) {
|
|
22
|
-
return (
|
|
23
|
-
<a
|
|
24
|
-
href={url}
|
|
25
|
-
target="_blank"
|
|
26
|
-
className="bg-white shadow py-2 px-5 rounded-full inline-flex items-center hover:opacity-80"
|
|
27
|
-
rel="noreferrer"
|
|
28
|
-
>
|
|
29
|
-
{label}
|
|
30
|
-
<ExternalIcon />
|
|
31
|
-
</a>
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function BoxFallback() {
|
|
36
|
-
return (
|
|
37
|
-
<div className="bg-white p-12 shadow-xl rounded-xl text-gray-900 h-60"></div>
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function StorefrontInfo() {
|
|
42
|
-
const {data} = useShopQuery({query: QUERY, preload: true});
|
|
43
|
-
const shopName = data ? data.shop.name : '';
|
|
44
|
-
const products = data && flattenConnection(data.products);
|
|
45
|
-
const collections = data && flattenConnection(data.collections);
|
|
46
|
-
const totalProducts = products && products.length;
|
|
47
|
-
const totalCollections = collections && collections.length;
|
|
48
|
-
|
|
49
|
-
const pluralize = (count, noun, suffix = 's') =>
|
|
50
|
-
`${count} ${noun}${count === 1 ? '' : suffix}`;
|
|
51
|
-
return (
|
|
52
|
-
<div className="bg-white p-12 shadow-xl rounded-xl text-gray-900">
|
|
53
|
-
<p className="text-md font-medium uppercase mb-4">Connected Storefront</p>
|
|
54
|
-
<h2 className="text-2xl font-bold mb-4">{shopName}</h2>
|
|
55
|
-
<p className="text-md">
|
|
56
|
-
{pluralize(totalProducts, 'Product')}
|
|
57
|
-
{', '}
|
|
58
|
-
{pluralize(totalCollections, 'Collection')}
|
|
59
|
-
</p>
|
|
60
|
-
{totalProducts === 0 && totalCollections === 0 && (
|
|
61
|
-
<div className="py-2 px-3 bg-red-100 text-md">
|
|
62
|
-
Use the{' '}
|
|
63
|
-
<a
|
|
64
|
-
href="https://shopify.dev/apps/tools/cli/getting-started"
|
|
65
|
-
className="text-primary font-mono font-bold underline"
|
|
66
|
-
target="_blank"
|
|
67
|
-
rel="noreferrer"
|
|
68
|
-
>
|
|
69
|
-
Shopify CLI
|
|
70
|
-
</a>{' '}
|
|
71
|
-
to populate sample products and collections.
|
|
72
|
-
</div>
|
|
73
|
-
)}
|
|
74
|
-
<hr className="my-4" />
|
|
75
|
-
<a
|
|
76
|
-
href="https://shopify.dev/custom-storefronts/hydrogen/getting-started/create#step-2-update-information-about-your-shopify-storefront"
|
|
77
|
-
className="text-md inline-flex items-center text-blue-700 font-medium hover:underline"
|
|
78
|
-
target="_blank"
|
|
79
|
-
rel="noreferrer"
|
|
80
|
-
>
|
|
81
|
-
Change your storefront access token
|
|
82
|
-
<ExternalIcon />
|
|
83
|
-
</a>
|
|
84
|
-
</div>
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function TemplateLinks() {
|
|
89
|
-
const {data} = useShopQuery({query: QUERY, preload: true});
|
|
90
|
-
const products = data && flattenConnection(data.products);
|
|
91
|
-
const collections = data && flattenConnection(data.collections);
|
|
92
|
-
|
|
93
|
-
const firstProduct = products && products.length ? products[0].handle : '';
|
|
94
|
-
const firstCollection = collections[0] ? collections[0].handle : '';
|
|
95
|
-
|
|
96
|
-
return (
|
|
97
|
-
<div className="bg-white p-12 md:p-12 shadow-xl rounded-xl text-gray-900">
|
|
98
|
-
<p className="text-md font-medium uppercase mb-4">
|
|
99
|
-
Explore the templates
|
|
100
|
-
</p>
|
|
101
|
-
<ul>
|
|
102
|
-
<li className="mb-4">
|
|
103
|
-
<Link
|
|
104
|
-
to={`/collections/${firstCollection}`}
|
|
105
|
-
className="text-md font-medium text-blue-700 hover:underline"
|
|
106
|
-
>
|
|
107
|
-
Collection template
|
|
108
|
-
</Link>
|
|
109
|
-
</li>
|
|
110
|
-
<li className="mb-4">
|
|
111
|
-
<Link
|
|
112
|
-
to={`/products/${firstProduct}`}
|
|
113
|
-
className="text-md font-medium text-blue-700 hover:underline"
|
|
114
|
-
>
|
|
115
|
-
Product template
|
|
116
|
-
</Link>
|
|
117
|
-
</li>
|
|
118
|
-
<li>
|
|
119
|
-
<Link
|
|
120
|
-
to="/error-page"
|
|
121
|
-
className="text-md font-medium text-blue-700 hover:underline"
|
|
122
|
-
>
|
|
123
|
-
404 template
|
|
124
|
-
</Link>
|
|
125
|
-
</li>
|
|
126
|
-
</ul>
|
|
127
|
-
</div>
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* A server component that displays the content on the homepage of the Hydrogen app
|
|
133
|
-
*/
|
|
134
|
-
export default function Welcome() {
|
|
135
|
-
return (
|
|
136
|
-
<div className="text-gray-900 pt-16 rounded-[40px] my-16 px-4 xl:px-12 bg-gradient-to-b from-white -mx-4 xl:-mx-12">
|
|
137
|
-
<div className="text-center mb-16">
|
|
138
|
-
<h1 className="font-extrabold mb-4 text-5xl md:text-7xl">
|
|
139
|
-
Hello, Hydrogen
|
|
140
|
-
</h1>
|
|
141
|
-
<p className="text-lg mb-8">
|
|
142
|
-
Welcome to your custom storefront. Let’s get building.
|
|
143
|
-
</p>
|
|
144
|
-
<div className="flex flex-col lg:flex-row justify-center items-center gap-8 text-gray-700">
|
|
145
|
-
<DocsButton
|
|
146
|
-
url="https://shopify.dev/custom-storefronts/hydrogen"
|
|
147
|
-
label="Browse Hydrogen documentation"
|
|
148
|
-
/>
|
|
149
|
-
<DocsButton url="/graphql" label="Open the GraphiQL explorer" />
|
|
150
|
-
<DocsButton
|
|
151
|
-
url="https://github.com/Shopify/hydrogen-examples"
|
|
152
|
-
label="Explore Hydrogen examples"
|
|
153
|
-
/>
|
|
154
|
-
</div>
|
|
155
|
-
</div>
|
|
156
|
-
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 lg:gap-16">
|
|
157
|
-
<Suspense fallback={<BoxFallback />}>
|
|
158
|
-
<StorefrontInfo />
|
|
159
|
-
</Suspense>
|
|
160
|
-
<Suspense fallback={<BoxFallback />}>
|
|
161
|
-
<TemplateLinks />
|
|
162
|
-
</Suspense>
|
|
163
|
-
</div>
|
|
164
|
-
</div>
|
|
165
|
-
);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const QUERY = gql`
|
|
169
|
-
query welcomeContent {
|
|
170
|
-
shop {
|
|
171
|
-
name
|
|
172
|
-
}
|
|
173
|
-
products(first: 250) {
|
|
174
|
-
edges {
|
|
175
|
-
node {
|
|
176
|
-
handle
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
collections(first: 250) {
|
|
181
|
-
edges {
|
|
182
|
-
node {
|
|
183
|
-
handle
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
`;
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
@tailwind base;
|
|
2
|
-
@tailwind components;
|
|
3
|
-
@tailwind utilities;
|
|
4
|
-
|
|
5
|
-
@layer utilities {
|
|
6
|
-
.scroll-snap-x {
|
|
7
|
-
scroll-snap-type: x mandatory;
|
|
8
|
-
}
|
|
9
|
-
.snap-start {
|
|
10
|
-
scroll-snap-align: start;
|
|
11
|
-
}
|
|
12
|
-
.snap-smooth {
|
|
13
|
-
scroll-behavior: smooth;
|
|
14
|
-
}
|
|
15
|
-
.snap-px-4 {
|
|
16
|
-
scroll-padding-left: 1rem;
|
|
17
|
-
scroll-padding-right: 1rem;
|
|
18
|
-
}
|
|
19
|
-
.no-scrollbar::-webkit-scrollbar {
|
|
20
|
-
display: none;
|
|
21
|
-
}
|
|
22
|
-
.no-scrollbar {
|
|
23
|
-
-ms-overflow-style: none; /* IE and Edge */
|
|
24
|
-
scrollbar-width: none; /* Firefox */
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
* {
|
|
29
|
-
font-variant-ligatures: none;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
html {
|
|
33
|
-
scroll-padding-top: 10rem;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
model-viewer::part(default-progress-mask) {
|
|
37
|
-
display: none;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
model-viewer::part(default-progress-bar) {
|
|
41
|
-
display: none;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
.gradient {
|
|
45
|
-
background: linear-gradient(
|
|
46
|
-
310deg,
|
|
47
|
-
rgba(255, 97, 0, 1),
|
|
48
|
-
white,
|
|
49
|
-
rgba(0, 197, 185, 1)
|
|
50
|
-
);
|
|
51
|
-
background-size: 600% 600%;
|
|
52
|
-
animation: gradient-animation 14s ease infinite;
|
|
53
|
-
|
|
54
|
-
/* prettier-ignore */
|
|
55
|
-
clip-path: polygon(100% 0%, 0% 0% , 0% 65%, 1% 64.95%, 2% 64.8%, 3% 64.6%, 4% 64.3%, 5% 63.9%, 6% 63.45%, 7% 62.9%, 8% 62.25%, 9% 61.55%, 10% 60.8%, 11% 59.95%, 12% 59.05%, 13% 58.1%, 14% 57.1%, 15% 56.05%, 16% 55%, 17% 53.9%, 18% 52.8%, 19% 51.65%, 20% 50.5%, 21% 49.35%, 22% 48.2%, 23% 47.05%, 24% 45.9%, 25% 44.8%, 26% 43.75%, 27% 42.75%, 28% 41.75%, 29% 40.8%, 30% 39.9%, 31% 39.1%, 32% 38.35%, 33% 37.65%, 34% 37.05%, 35% 36.5%, 36% 36.05%, 37% 35.65%, 38% 35.35%, 39% 35.15%, 40% 35.05%, 41% 35%, 42% 35.05%, 43% 35.2%, 44% 35.45%, 45% 35.75%, 46% 36.15%, 47% 36.65%, 48% 37.2%, 49% 37.85%, 50% 38.55%, 51% 39.35%, 52% 40.2%, 53% 41.1%, 54% 42.05%, 55% 43.05%, 56% 44.1%, 57% 45.15%, 58% 46.3%, 59% 47.4%, 60% 48.55%, 61% 49.7%, 62% 50.85%, 63% 52%, 64% 53.15%, 65% 54.25%, 66% 55.35%, 67% 56.4%, 68% 57.45%, 69% 58.4%, 70% 59.35%, 71% 60.2%, 72% 61.05%, 73% 61.8%, 74% 62.45%, 75% 63.05%, 76% 63.6%, 77% 64.05%, 78% 64.4%, 79% 64.7%, 80% 64.85%, 81% 65%, 82% 65%, 83% 64.9%, 84% 64.75%, 85% 64.5%, 86% 64.2%, 87% 63.75%, 88% 63.25%, 89% 62.7%, 90% 62.05%, 91% 61.3%, 92% 60.5%, 93% 59.65%, 94% 58.75%, 95% 57.8%, 96% 56.8%, 97% 55.75%, 98% 54.65%, 99% 53.55%, 100% 52.4%);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
@keyframes gradient-animation {
|
|
59
|
-
0% {
|
|
60
|
-
background-position: 97% 0%;
|
|
61
|
-
}
|
|
62
|
-
50% {
|
|
63
|
-
background-position: 4% 100%;
|
|
64
|
-
}
|
|
65
|
-
100% {
|
|
66
|
-
background-position: 97% 0%;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
MediaFileFragment,
|
|
3
|
-
ProductProviderFragment,
|
|
4
|
-
useShopQuery,
|
|
5
|
-
flattenConnection,
|
|
6
|
-
RawHtml,
|
|
7
|
-
Seo,
|
|
8
|
-
} from '@shopify/hydrogen';
|
|
9
|
-
import gql from 'graphql-tag';
|
|
10
|
-
|
|
11
|
-
import LoadMoreProducts from '../../components/LoadMoreProducts.client';
|
|
12
|
-
import Layout from '../../components/Layout.server';
|
|
13
|
-
import ProductCard from '../../components/ProductCard';
|
|
14
|
-
import NotFound from '../../components/NotFound.server';
|
|
15
|
-
|
|
16
|
-
export default function Collection({
|
|
17
|
-
country = {isoCode: 'US'},
|
|
18
|
-
collectionProductCount = 24,
|
|
19
|
-
params,
|
|
20
|
-
}) {
|
|
21
|
-
const {handle} = params;
|
|
22
|
-
const {data} = useShopQuery({
|
|
23
|
-
query: QUERY,
|
|
24
|
-
variables: {
|
|
25
|
-
handle,
|
|
26
|
-
country: country.isoCode,
|
|
27
|
-
numProducts: collectionProductCount,
|
|
28
|
-
},
|
|
29
|
-
preload: true,
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
if (data?.collection == null) {
|
|
33
|
-
return <NotFound />;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const collection = data.collection;
|
|
37
|
-
const products = flattenConnection(collection.products);
|
|
38
|
-
const hasNextPage = data.collection.products.pageInfo.hasNextPage;
|
|
39
|
-
|
|
40
|
-
return (
|
|
41
|
-
<Layout>
|
|
42
|
-
{/* the seo object will be expose in API version 2022-04 or later */}
|
|
43
|
-
<Seo type="collection" data={{seo: {}, ...collection}} />
|
|
44
|
-
<h1 className="font-bold text-4xl md:text-5xl text-gray-900 mb-6 mt-6">
|
|
45
|
-
{collection.title}
|
|
46
|
-
</h1>
|
|
47
|
-
<RawHtml string={collection.descriptionHtml} className="text-lg" />
|
|
48
|
-
<p className="text-sm text-gray-500 mt-5 mb-5">
|
|
49
|
-
{products.length} {products.length > 1 ? 'products' : 'product'}
|
|
50
|
-
</p>
|
|
51
|
-
<ul className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 mb-16">
|
|
52
|
-
{products.map((product) => (
|
|
53
|
-
<li key={product.id}>
|
|
54
|
-
<ProductCard product={product} />
|
|
55
|
-
</li>
|
|
56
|
-
))}
|
|
57
|
-
</ul>
|
|
58
|
-
{hasNextPage && (
|
|
59
|
-
<LoadMoreProducts startingCount={collectionProductCount} />
|
|
60
|
-
)}
|
|
61
|
-
</Layout>
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const QUERY = gql`
|
|
66
|
-
query CollectionDetails(
|
|
67
|
-
$handle: String!
|
|
68
|
-
$country: CountryCode
|
|
69
|
-
$numProducts: Int!
|
|
70
|
-
$includeReferenceMetafieldDetails: Boolean = false
|
|
71
|
-
$numProductMetafields: Int = 0
|
|
72
|
-
$numProductVariants: Int = 250
|
|
73
|
-
$numProductMedia: Int = 6
|
|
74
|
-
$numProductVariantMetafields: Int = 0
|
|
75
|
-
$numProductVariantSellingPlanAllocations: Int = 0
|
|
76
|
-
$numProductSellingPlanGroups: Int = 0
|
|
77
|
-
$numProductSellingPlans: Int = 0
|
|
78
|
-
) @inContext(country: $country) {
|
|
79
|
-
collection(handle: $handle) {
|
|
80
|
-
id
|
|
81
|
-
title
|
|
82
|
-
description
|
|
83
|
-
descriptionHtml
|
|
84
|
-
image {
|
|
85
|
-
url
|
|
86
|
-
width
|
|
87
|
-
height
|
|
88
|
-
}
|
|
89
|
-
products(first: $numProducts) {
|
|
90
|
-
edges {
|
|
91
|
-
node {
|
|
92
|
-
vendor
|
|
93
|
-
...ProductProviderFragment
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
pageInfo {
|
|
97
|
-
hasNextPage
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
${MediaFileFragment}
|
|
104
|
-
${ProductProviderFragment}
|
|
105
|
-
`;
|
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
useShopQuery,
|
|
3
|
-
flattenConnection,
|
|
4
|
-
ProductProviderFragment,
|
|
5
|
-
Image,
|
|
6
|
-
Link,
|
|
7
|
-
Seo,
|
|
8
|
-
CacheDays,
|
|
9
|
-
} from '@shopify/hydrogen';
|
|
10
|
-
import gql from 'graphql-tag';
|
|
11
|
-
|
|
12
|
-
import Layout from '../components/Layout.server';
|
|
13
|
-
import FeaturedCollection from '../components/FeaturedCollection';
|
|
14
|
-
import ProductCard from '../components/ProductCard';
|
|
15
|
-
import Welcome from '../components/Welcome.server';
|
|
16
|
-
import {Suspense} from 'react';
|
|
17
|
-
|
|
18
|
-
export default function Index({country = {isoCode: 'US'}}) {
|
|
19
|
-
return (
|
|
20
|
-
<Layout hero={<GradientBackground />}>
|
|
21
|
-
<Suspense fallback={null}>
|
|
22
|
-
<SeoForHomepage />
|
|
23
|
-
</Suspense>
|
|
24
|
-
<div className="relative mb-12">
|
|
25
|
-
<Welcome />
|
|
26
|
-
<Suspense fallback={<BoxFallback />}>
|
|
27
|
-
<FeaturedProductsBox country={country} />
|
|
28
|
-
</Suspense>
|
|
29
|
-
<Suspense fallback={<BoxFallback />}>
|
|
30
|
-
<FeaturedCollectionBox country={country} />
|
|
31
|
-
</Suspense>
|
|
32
|
-
</div>
|
|
33
|
-
</Layout>
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function SeoForHomepage() {
|
|
38
|
-
const {
|
|
39
|
-
data: {
|
|
40
|
-
shop: {
|
|
41
|
-
name: shopName,
|
|
42
|
-
primaryDomain: {url: shopUrl},
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
} = useShopQuery({
|
|
46
|
-
query: SEO_QUERY,
|
|
47
|
-
cache: CacheDays(),
|
|
48
|
-
preload: true,
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
return (
|
|
52
|
-
<Seo
|
|
53
|
-
type="homepage"
|
|
54
|
-
data={{
|
|
55
|
-
title: shopName,
|
|
56
|
-
url: shopUrl,
|
|
57
|
-
}}
|
|
58
|
-
/>
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function BoxFallback() {
|
|
63
|
-
return <div className="bg-white p-12 shadow-xl rounded-xl mb-10 h-40"></div>;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function FeaturedProductsBox({country}) {
|
|
67
|
-
const {data} = useShopQuery({
|
|
68
|
-
query: QUERY,
|
|
69
|
-
variables: {
|
|
70
|
-
country: country.isoCode,
|
|
71
|
-
},
|
|
72
|
-
preload: true,
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
const collections = data ? flattenConnection(data.collections) : [];
|
|
76
|
-
const featuredProductsCollection = collections[0];
|
|
77
|
-
const featuredProducts = featuredProductsCollection
|
|
78
|
-
? flattenConnection(featuredProductsCollection.products)
|
|
79
|
-
: null;
|
|
80
|
-
|
|
81
|
-
return (
|
|
82
|
-
<div className="bg-white p-12 shadow-xl rounded-xl mb-10">
|
|
83
|
-
{featuredProductsCollection ? (
|
|
84
|
-
<>
|
|
85
|
-
<div className="flex justify-between items-center mb-8 text-md font-medium">
|
|
86
|
-
<span className="text-black uppercase">
|
|
87
|
-
{featuredProductsCollection.title}
|
|
88
|
-
</span>
|
|
89
|
-
<span className="hidden md:inline-flex">
|
|
90
|
-
<Link
|
|
91
|
-
to={`/collections/${featuredProductsCollection.handle}`}
|
|
92
|
-
className="text-blue-600 hover:underline"
|
|
93
|
-
>
|
|
94
|
-
Shop all
|
|
95
|
-
</Link>
|
|
96
|
-
</span>
|
|
97
|
-
</div>
|
|
98
|
-
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 mb-8">
|
|
99
|
-
{featuredProducts.map((product) => (
|
|
100
|
-
<div key={product.id}>
|
|
101
|
-
<ProductCard product={product} />
|
|
102
|
-
</div>
|
|
103
|
-
))}
|
|
104
|
-
</div>
|
|
105
|
-
<div className="md:hidden text-center">
|
|
106
|
-
<Link
|
|
107
|
-
to={`/collections/${featuredProductsCollection.handle}`}
|
|
108
|
-
className="text-blue-600"
|
|
109
|
-
>
|
|
110
|
-
Shop all
|
|
111
|
-
</Link>
|
|
112
|
-
</div>
|
|
113
|
-
</>
|
|
114
|
-
) : null}
|
|
115
|
-
</div>
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function FeaturedCollectionBox({country}) {
|
|
120
|
-
const {data} = useShopQuery({
|
|
121
|
-
query: QUERY,
|
|
122
|
-
variables: {
|
|
123
|
-
country: country.isoCode,
|
|
124
|
-
},
|
|
125
|
-
preload: true,
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
const collections = data ? flattenConnection(data.collections) : [];
|
|
129
|
-
const featuredCollection =
|
|
130
|
-
collections && collections.length > 1 ? collections[1] : collections[0];
|
|
131
|
-
|
|
132
|
-
return <FeaturedCollection collection={featuredCollection} />;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function GradientBackground() {
|
|
136
|
-
return (
|
|
137
|
-
<div className="fixed top-0 w-full h-3/5 overflow-hidden">
|
|
138
|
-
<div className="absolute w-full h-full bg-gradient-to-t from-gray-50 z-10" />
|
|
139
|
-
|
|
140
|
-
<svg
|
|
141
|
-
viewBox="0 0 960 743"
|
|
142
|
-
fill="none"
|
|
143
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
144
|
-
xmlnsXlink="http://www.w3.org/1999/xlink"
|
|
145
|
-
className="filter blur-[30px]"
|
|
146
|
-
aria-hidden="true"
|
|
147
|
-
>
|
|
148
|
-
<defs>
|
|
149
|
-
<path fill="#fff" d="M0 0h960v540H0z" id="reuse-0" />
|
|
150
|
-
</defs>
|
|
151
|
-
<g clipPath="url(#a)">
|
|
152
|
-
<use xlinkHref="#reuse-0" />
|
|
153
|
-
<path d="M960 0H0v743h960V0Z" fill="#7CFBEE" />
|
|
154
|
-
<path
|
|
155
|
-
d="M831 380c200.48 0 363-162.521 363-363s-162.52-363-363-363c-200.479 0-363 162.521-363 363s162.521 363 363 363Z"
|
|
156
|
-
fill="#4F98D0"
|
|
157
|
-
/>
|
|
158
|
-
<path
|
|
159
|
-
d="M579 759c200.479 0 363-162.521 363-363S779.479 33 579 33 216 195.521 216 396s162.521 363 363 363Z"
|
|
160
|
-
fill="#7CFBEE"
|
|
161
|
-
/>
|
|
162
|
-
<path
|
|
163
|
-
d="M178 691c200.479 0 363-162.521 363-363S378.479-35 178-35c-200.4794 0-363 162.521-363 363s162.5206 363 363 363Z"
|
|
164
|
-
fill="#4F98D0"
|
|
165
|
-
/>
|
|
166
|
-
<path
|
|
167
|
-
d="M490 414c200.479 0 363-162.521 363-363S690.479-312 490-312 127-149.479 127 51s162.521 363 363 363Z"
|
|
168
|
-
fill="#4F98D0"
|
|
169
|
-
/>
|
|
170
|
-
<path
|
|
171
|
-
d="M354 569c200.479 0 363-162.521 363-363 0-200.47937-162.521-363-363-363S-9 5.52063-9 206c0 200.479 162.521 363 363 363Z"
|
|
172
|
-
fill="#7CFBEE"
|
|
173
|
-
/>
|
|
174
|
-
<path
|
|
175
|
-
d="M630 532c200.479 0 363-162.521 363-363 0-200.4794-162.521-363-363-363S267-31.4794 267 169c0 200.479 162.521 363 363 363Z"
|
|
176
|
-
fill="#4F98D0"
|
|
177
|
-
/>
|
|
178
|
-
</g>
|
|
179
|
-
<path fill="#fff" d="M0 540h960v203H0z" />
|
|
180
|
-
<defs>
|
|
181
|
-
<clipPath id="a">
|
|
182
|
-
<use xlinkHref="#reuse-0" />
|
|
183
|
-
</clipPath>
|
|
184
|
-
</defs>
|
|
185
|
-
</svg>
|
|
186
|
-
</div>
|
|
187
|
-
);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
const SEO_QUERY = gql`
|
|
191
|
-
query homeShopInfo {
|
|
192
|
-
shop {
|
|
193
|
-
name
|
|
194
|
-
description
|
|
195
|
-
primaryDomain {
|
|
196
|
-
url
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
`;
|
|
201
|
-
|
|
202
|
-
const QUERY = gql`
|
|
203
|
-
query indexContent(
|
|
204
|
-
$country: CountryCode
|
|
205
|
-
$numCollections: Int = 2
|
|
206
|
-
$numProducts: Int = 3
|
|
207
|
-
$includeReferenceMetafieldDetails: Boolean = false
|
|
208
|
-
$numProductMetafields: Int = 0
|
|
209
|
-
$numProductVariants: Int = 250
|
|
210
|
-
$numProductMedia: Int = 1
|
|
211
|
-
$numProductVariantMetafields: Int = 10
|
|
212
|
-
$numProductVariantSellingPlanAllocations: Int = 0
|
|
213
|
-
$numProductSellingPlanGroups: Int = 0
|
|
214
|
-
$numProductSellingPlans: Int = 0
|
|
215
|
-
) @inContext(country: $country) {
|
|
216
|
-
collections(first: $numCollections) {
|
|
217
|
-
edges {
|
|
218
|
-
node {
|
|
219
|
-
descriptionHtml
|
|
220
|
-
description
|
|
221
|
-
handle
|
|
222
|
-
id
|
|
223
|
-
title
|
|
224
|
-
image {
|
|
225
|
-
...ImageFragment
|
|
226
|
-
}
|
|
227
|
-
products(first: $numProducts) {
|
|
228
|
-
edges {
|
|
229
|
-
node {
|
|
230
|
-
...ProductProviderFragment
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
${ProductProviderFragment}
|
|
240
|
-
${Image.Fragment}
|
|
241
|
-
`;
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import {useShopQuery, RawHtml, Seo} from '@shopify/hydrogen';
|
|
2
|
-
import gql from 'graphql-tag';
|
|
3
|
-
|
|
4
|
-
import Layout from '../../components/Layout.server';
|
|
5
|
-
import NotFound from '../../components/NotFound.server';
|
|
6
|
-
|
|
7
|
-
export default function Page({params}) {
|
|
8
|
-
const {handle} = params;
|
|
9
|
-
const {data} = useShopQuery({query: QUERY, variables: {handle}});
|
|
10
|
-
|
|
11
|
-
if (!data.pageByHandle) {
|
|
12
|
-
return <NotFound />;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const page = data.pageByHandle;
|
|
16
|
-
|
|
17
|
-
return (
|
|
18
|
-
<Layout>
|
|
19
|
-
<Seo type="page" data={page} />
|
|
20
|
-
<h1 className="text-2xl font-bold">{page.title}</h1>
|
|
21
|
-
<RawHtml string={page.body} className="prose mt-8" />
|
|
22
|
-
</Layout>
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const QUERY = gql`
|
|
27
|
-
query PageDetails($handle: String!) {
|
|
28
|
-
pageByHandle(handle: $handle) {
|
|
29
|
-
title
|
|
30
|
-
body
|
|
31
|
-
seo {
|
|
32
|
-
title
|
|
33
|
-
description
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
`;
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import {useShopQuery, ProductProviderFragment, Seo} from '@shopify/hydrogen';
|
|
2
|
-
import gql from 'graphql-tag';
|
|
3
|
-
|
|
4
|
-
import ProductDetails from '../../components/ProductDetails.client';
|
|
5
|
-
import NotFound from '../../components/NotFound.server';
|
|
6
|
-
import Layout from '../../components/Layout.server';
|
|
7
|
-
|
|
8
|
-
export default function Product({country = {isoCode: 'US'}, params}) {
|
|
9
|
-
const {handle} = params;
|
|
10
|
-
|
|
11
|
-
const {
|
|
12
|
-
data: {product},
|
|
13
|
-
} = useShopQuery({
|
|
14
|
-
query: QUERY,
|
|
15
|
-
variables: {
|
|
16
|
-
country: country.isoCode,
|
|
17
|
-
handle,
|
|
18
|
-
},
|
|
19
|
-
preload: true,
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
if (!product) {
|
|
23
|
-
return <NotFound />;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return (
|
|
27
|
-
<Layout>
|
|
28
|
-
<Seo type="product" data={product} />
|
|
29
|
-
<ProductDetails product={product} />
|
|
30
|
-
</Layout>
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const QUERY = gql`
|
|
35
|
-
query product(
|
|
36
|
-
$country: CountryCode
|
|
37
|
-
$handle: String!
|
|
38
|
-
$includeReferenceMetafieldDetails: Boolean = true
|
|
39
|
-
$numProductMetafields: Int = 20
|
|
40
|
-
$numProductVariants: Int = 250
|
|
41
|
-
$numProductMedia: Int = 6
|
|
42
|
-
$numProductVariantMetafields: Int = 10
|
|
43
|
-
$numProductVariantSellingPlanAllocations: Int = 0
|
|
44
|
-
$numProductSellingPlanGroups: Int = 0
|
|
45
|
-
$numProductSellingPlans: Int = 0
|
|
46
|
-
) @inContext(country: $country) {
|
|
47
|
-
product: product(handle: $handle) {
|
|
48
|
-
id
|
|
49
|
-
description
|
|
50
|
-
vendor
|
|
51
|
-
seo {
|
|
52
|
-
title
|
|
53
|
-
description
|
|
54
|
-
}
|
|
55
|
-
featuredImage {
|
|
56
|
-
url
|
|
57
|
-
height
|
|
58
|
-
width
|
|
59
|
-
altText
|
|
60
|
-
}
|
|
61
|
-
...ProductProviderFragment
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
${ProductProviderFragment}
|
|
66
|
-
`;
|