Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
334944c
Inits new demo store template
benjaminsehl May 27, 2022
619a8bd
Update package.json
May 27, 2022
c53b04f
Use `gql` from `hydrogen` in demo store v2
lordofthecactus May 27, 2022
d06ff87
Remove server utilities from client build (#1363)
frandiox May 27, 2022
490e359
remove stray console.log (#1364)
May 27, 2022
333dd7a
Prevent encoded props from double decoding (#1360)
blittle May 27, 2022
68ae759
Update stackblitz workflow to manually update files (#1365)
jplhomer May 27, 2022
383181a
Add rule override (#1367)
May 27, 2022
900342f
Adds @types/react to typescript example (#1362)
JrFelix540 May 27, 2022
e588fb5
Update docs to describe the difference between experimental and unsta…
jplhomer May 27, 2022
540b273
Explicitly log errors for Flight onError (#1320)
jplhomer May 27, 2022
9f8f1a9
Bump hydrogen eslint plugin version (#1368)
jplhomer May 27, 2022
003d8a2
Drop prefixes from template names (#1369)
May 27, 2022
ad829d2
Typescript updates (#1374)
frehner May 27, 2022
9b2ad1f
Fix Image typescript issues (#1371)
frehner May 27, 2022
3bf9668
Update yarn.lock
benjaminsehl May 28, 2022
7f358df
Adds basic layout components and content for 404
benjaminsehl May 30, 2022
e997b80
@benjaminsehl/demo store neue (#1387)
benjaminsehl May 31, 2022
abd5fdd
Updates Icons to work with SSR
benjaminsehl May 31, 2022
2824591
Removes custom spacing from Tailwind config
benjaminsehl May 31, 2022
fe7c6b5
Updates temp country banner
benjaminsehl May 31, 2022
f16f2bc
Refactors product card, adds search page, beginning of product page
benjaminsehl May 31, 2022
a599caf
Adds search functionality, adds real data to homepage, improves compo…
benjaminsehl May 31, 2022
bd0d775
Completes desktop hero with dynamic data
benjaminsehl May 31, 2022
d1b6475
Improves layout and adds data for homepage, cart, header, product car…
benjaminsehl May 31, 2022
466f740
Updates to locations, collections, products all
benjaminsehl May 31, 2022
6df7d98
Style consistency updates and addition of dark mode
benjaminsehl May 31, 2022
bec34ed
Adds functioning search bar on search page
benjaminsehl May 31, 2022
152abc1
Adds queries and dynamic data for components
benjaminsehl Jun 1, 2022
5eb1f23
Update styling on hero and search
benjaminsehl Jun 1, 2022
1b2f33e
Yarn format
benjaminsehl Jun 1, 2022
145defe
Updates to hero and search
benjaminsehl Jun 1, 2022
c464e92
Updates with main branch
benjaminsehl Jun 1, 2022
b712c21
Revert "Updates to hero and search"
benjaminsehl Jun 1, 2022
dd5a3b3
Style tweaks to header
benjaminsehl Jun 1, 2022
dcfb0b1
Complete locations template
benjaminsehl Jun 1, 2022
3faf28b
Update Location template layout
benjaminsehl Jun 1, 2022
636481a
Demo store neue: collection pagination (#1400)
scottdixon Jun 1, 2022
0c456db
Dynamic Product Swimlane & Mobile Layouts (#1412)
benjaminsehl Jun 2, 2022
3440639
@benjaminsehl/pdp demo store neue (#1414)
benjaminsehl Jun 2, 2022
e53b974
Added account pages from demo-store (#1410)
davecyen Jun 2, 2022
f05897c
adds cart functionality (#1417)
benjaminsehl Jun 2, 2022
94a8424
Wire up cart page
benjaminsehl Jun 2, 2022
fd0806f
Fixes typeof error in swimlane
benjaminsehl Jun 2, 2022
3bdf9b7
Wires up cart data
benjaminsehl Jun 2, 2022
199ad7e
Demo store neue: Intersection Observer for infinite scroll (#1421)
scottdixon Jun 2, 2022
0818579
Dy orders (#1420)
davecyen Jun 2, 2022
2311691
Demo store neue: clean up country selector (#1436)
scottdixon Jun 3, 2022
252f7ec
Renames metaobjects to contentEntries
benjaminsehl Jun 3, 2022
4de9667
Updates metaobject references to contentEntry
benjaminsehl Jun 3, 2022
c75b463
Minor visual fixes and a catch for a bug with availableOnSale
benjaminsehl Jun 3, 2022
6817ce6
Moves Neue to main demo store, moves existing demo store to demo-stor…
benjaminsehl Jun 3, 2022
97119fb
Display order history as a grid of cards (#1440)
davecyen Jun 4, 2022
ba43a31
Fix new demo store build after update to [email protected] (#1454)
lordofthecactus Jun 8, 2022
77a7aed
Revert "Fix new demo store build after update to [email protected] (#14…
lordofthecactus Jun 8, 2022
b32d4f9
Upgrade Demo Store Neue to v23 (#1467)
benjaminsehl Jun 8, 2022
2e03112
Remove package lock file
lordofthecactus Jun 8, 2022
164c261
Update demo store neue from main branch
lordofthecactus Jun 8, 2022
aa7312d
Temporarily comment out missing account components and fixes small is…
lordofthecactus Jun 8, 2022
75329a8
Update to `[email protected]`
lordofthecactus Jun 8, 2022
a3a7609
Fix graphql schema
lordofthecactus Jun 8, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions templates/demo-store-neue/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Hydrogen Demo Store

Hydrogen is a React framework and SDK that you can use to build fast and dynamic Shopify custom storefronts.

[Check out the docs](https://shopify.dev/custom-storefronts/hydrogen)

[Run this template on StackBlitz](https://stackblitz.com/github/Shopify/hydrogen/tree/stackblitz/templates/demo-store)

## Getting started

**Requirements:**

- Node.js version 16.5.0 or higher
- Yarn

```bash
yarn
yarn dev
```

Remember to update `hydrogen.config.js` with your shop's domain and Storefront API token!

## Building for production

```bash
yarn build
```

## Previewing a production build

To run a local preview of your Hydrogen app in an environment similar to Oxygen, build your Hydrogen app and then run `yarn preview`:

```bash
yarn build
yarn preview
```
25 changes: 25 additions & 0 deletions templates/demo-store-neue/hydrogen.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {defineConfig} from '@shopify/hydrogen/config';
import {
CookieSessionStorage,
PerformanceMetricsServerAnalyticsConnector,
ShopifyServerAnalyticsConnector,
} from '@shopify/hydrogen';

export default defineConfig({
shopify: {
storeDomain: 'hydrogen-preview.myshopify.com',
storefrontToken: '3b580e70970c4528da70c98e097c2fa0',
storefrontApiVersion: 'unstable',
},
session: CookieSessionStorage('__session', {
path: '/',
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'strict',
maxAge: 60 * 60 * 24 * 30,
}),
serverAnalyticsConnectors: [
PerformanceMetricsServerAnalyticsConnector,
ShopifyServerAnalyticsConnector,
],
});
19 changes: 19 additions & 0 deletions templates/demo-store-neue/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<!-- TODO: Use Admin API to get brand logo (SVG) and -->
<link rel="icon" type="image/svg+xml" href="/src/assets/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- TODO: This should be automatically replaced when generated -->
<title>Hydrogen Demo Store</title>
<link rel="stylesheet" href="/src/styles/index.css" />
<link rel="preconnect" href="https://cdn.shopify.com" />
<link rel="preconnect" href="https://shop.app/" />
<link rel="preconnect" href="https://hydrogen-preview.myshopify.com/" />
</head>
<body>
<div id="root"></div>
<script type="module" src="/@shopify/hydrogen/entry-client"></script>
</body>
</html>
7 changes: 7 additions & 0 deletions templates/demo-store-neue/jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"compilerOptions": {
"paths": {
"~/*": ["./src/*"]
}
}
}
49 changes: 49 additions & 0 deletions templates/demo-store-neue/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"name": "demo-store-neue",
"description": "Hello world template for @shopify/hydrogen",
"version": "0.0.0",
"license": "MIT",
"private": true,
"scripts": {
"dev": "shopify hydrogen dev",
"build": "shopify hydrogen build",
"preview": "shopify hydrogen preview",
"lint": "eslint --ext .js,.jsx,.ts,.tsx src"
},
"devDependencies": {
"@shopify/cli": "^3.0.11",
"@shopify/cli-hydrogen": "^3.0.11",
"@shopify/prettier-config": "^1.1.2",
"@tailwindcss/forms": "^0.5.2",
"@tailwindcss/typography": "^0.5.2",
"eslint": "^8.16.0",
"eslint-plugin-hydrogen": "^0.12.2",
"postcss": "^8.4.14",
"postcss-import": "^14.1.0",
"postcss-preset-env": "^7.6.0",
"prettier": "^2.3.2",
"tailwindcss": "^3.0.24",
"vite": "^2.9.0"
},
"prettier": "@shopify/prettier-config",
"dependencies": {
"@headlessui/react": "^1.6.3",
"@heroicons/react": "^1.0.6",
"@shopify/hydrogen": "^0.23.0",
"clsx": "^1.1.1",
"eslint-plugin-react": "^7.29.3",
"eslint-plugin-react-hooks": "^4.2.0",
"graphql-tag": "^2.12.6",
"install": "^0.13.0",
"npm": "^8.12.1",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-use": "^17.4.0",
"title": "^3.4.4",
"ts-node": "^10.8.0",
"turbo": "^1.2.8",
"typescript": "^4.7.2",
"typographic-base": "^1.0.4",
"vite": "^2.9.0"
}
}
10 changes: 10 additions & 0 deletions templates/demo-store-neue/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = {
plugins: {
'postcss-import': {},
'tailwindcss/nesting': {},
tailwindcss: {},
'postcss-preset-env': {
features: {'nesting-rules': false},
},
},
};
33 changes: 33 additions & 0 deletions templates/demo-store-neue/src/App.server.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import renderHydrogen from '@shopify/hydrogen/entry-server';
import {
Route,
Router,
FileRoutes,
ShopifyProvider,
CartProvider,
ShopifyAnalytics,
PerformanceMetrics,
PerformanceMetricsDebug,
} from '@shopify/hydrogen';
import {Suspense} from 'react';
import {NotFound} from './components/pages';

function App({routes}) {
return (
<Suspense fallback={null}>
<ShopifyProvider>
<CartProvider>
<Router>
<FileRoutes routes={routes} />
<Route path="*" page={<NotFound />} />
</Router>
</CartProvider>
<PerformanceMetrics />
{import.meta.env.DEV && <PerformanceMetricsDebug />}
<ShopifyAnalytics />
</ShopifyProvider>
</Suspense>
);
}

export default renderHydrogen(App);
28 changes: 28 additions & 0 deletions templates/demo-store-neue/src/assets/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions templates/demo-store-neue/src/components/AccountIcon.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* A shared component that specifies the icon to represent an account
*/
export default function AccountIcon() {
return (
<svg
width="40"
height="40"
viewBox="0 0 40 40"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="20" cy="10.5" r="4.5" stroke="#374151" strokeWidth="2" />
<path
d="M20 19C13.4375 19 9.5 20.2857 9.5 28H30.5C30.5 20.2857 26.5625 19 20 19Z"
stroke="#374151"
strokeWidth="2"
/>
</svg>
);
}
14 changes: 14 additions & 0 deletions templates/demo-store-neue/src/components/LogoutButton.client.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {useCallback} from 'react';

export default function LogoutButton(props) {
const logout = useCallback(() => {
fetch('/account/logout', {method: 'POST'}).then(
() => (window.location.href = '/'),
);
}, []);
return (
<button {...props} onClick={logout}>
Sign out
</button>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import {useCallback, useState, Suspense} from 'react';
import {useCountry, fetchSync} from '@shopify/hydrogen';
import {Listbox} from '@headlessui/react';
import {IconChevronDown} from '~/components/elements';

/**
* A client component that selects the appropriate country to display for products on a website
*/
export default function CountrySelector() {
const [listboxOpen, setListboxOpen] = useState(false);
const [selectedCountry] = useCountry();

const setCountry = useCallback(({isoCode, name}) => {
fetch(`/api/countries`, {
body: JSON.stringify({isoCode, name}),
method: 'POST',
}).then(() => {
window.location.reload();
});
}, []);

return (
<div className="relative">
<Listbox onChange={setCountry}>
{({open}) => {
setTimeout(() => setListboxOpen(open));
return (
<>
<Listbox.Button className="flex items-center justify-between w-full border border-gray-500 p-2 rounded-sm">
<span className="">{selectedCountry.name}</span>
<IconChevronDown
className={`w-5 h-5 transition-transform duration-300 ${
open ? 'rotate-180' : null
}`}
/>
</Listbox.Button>

<Listbox.Options className="absolute z-10 mt-2 black border border-gray-500 p-2 w-full">
<div className="max-h-48 overflow-y-auto">
{listboxOpen && (
<Suspense fallback={<div>Loading…</div>}>
<Countries
selectedCountry={selectedCountry}
getClassName={(active) => {
return (
`w-full cursor-pointer py-2 flex justify-start items-center text-left cursor-pointer` +
`rounded ${active ? '' : null}`
);
}}
/>
</Suspense>
)}
</div>
</Listbox.Options>
</>
);
}}
</Listbox>
</div>
);
}

export function Countries({selectedCountry, getClassName}) {
// TODO: We should have this handled inside this component, no?
const countries = fetchSync('/api/countries').json();

return countries.map((country) => {
const isSelected = country.isoCode === selectedCountry.isoCode;
return (
<Listbox.Option key={country.isoCode} value={country}>
{({active}) => (
<div className={getClassName(active)}>
{country.name}
{isSelected ? (
<span className="ml-2">
<CheckIcon />
</span>
) : null}
</div>
)}
</Listbox.Option>
);
});
}

export function CheckIcon() {
return (
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
d="M7 10L9 12L13 8M19 10C19 14.9706 14.9706 19 10 19C5.02944 19 1 14.9706 1 10C1 5.02944 5.02944 1 10 1C14.9706 1 19 5.02944 19 10Z"
stroke="#FFFFFF"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {useMoney} from '@shopify/hydrogen';

/**
* A client component that defines the currency code, currency symbol, and amount of a product
*/
export default function MoneyPrice({money}) {
const {currencyCode, currencyNarrowSymbol, amount} = useMoney(money);
return (
<span className="text-black text-md">
{currencyCode}
{currencyNarrowSymbol}
{amount}
</span>
);
}
Loading