shopify / hydrogen-v1 Goto Github PK
View Code? Open in Web Editor NEWReact-based framework for building dynamic, Shopify-powered custom storefronts.
Home Page: https://shopify.github.io/hydrogen-v1/
License: MIT License
React-based framework for building dynamic, Shopify-powered custom storefronts.
Home Page: https://shopify.github.io/hydrogen-v1/
License: MIT License
We need to support i18n (internationalization). How do we do this? What does this mean?
๐ Hi! I've recently been looking in how we can best support third-party integrations in Hydrogen. While Hydrogen is typically focused on serving components from our own first-party storefront API, most headless merchants still end up needing to integrate with third-party services. I've been looking into how we can be as opinionated as possible when it comes to this integration so that we can offer much better performance & ergonomics than manually fetch
ing an external API on the client and massaging all the data yourself.
We've been documenting some thoughts about how we can best achieve that over here, but ultimately we think we can add the most value to fetching third-party data with three things: caching, batching, and mapping. Why these three strategies?
This idea in the form of a code example illustrates what the ergonomics of all server fetches in Hydrogen could look like if you squinted:
const query = gql`
query product($handle: String!) {
product(handle: $handle) {
id
}
}
`;
// These three shop queries are batched across hook calls (or across components within a Suspense boundary) into a single GraphQL request
const {data: data1} = useBatchedGraphQLQuery(query, { handle });
// Duplicate query detected while batching, no need to perform additional work & hashes to the same cache key
const {data: data2} = useBatchedGraphQLQuery(query, { handle });
// Cache-aware batching crafts the smallest request necessary, incorporates individual cache hits and makes use of H2 caching strategy
const {data: data3} = useBatchedGraphQLQuery(query, { handle: 'foo' }, {cache: { maxAge: 10 }});
const selectionSet = gql`{
title
upc
}; `
// Takes an existing Shopify product record and request data mapped to it via foreign key in external CMS
const {data: foo1} = useBatchedRecordsQuery(data.product, selectionSet, new SanityService(...));
// Batches many records with the same selection set within the same query,
// alongside other batched queries to the same service, while caching some records differentially
const {data: foo2} = useBatchedRecordsQuery(
{id: 'gid://shopify/Product/673085082834431'},
selectionSet,
new SanityService(...),
{ cache: { maxAge: 1} },
);
There's even a "working" prototype with comments for something similar if you want do just dive right in! But in trying to implement this, a few complications arose, and they mostly center around Hydrogen's use of the react-query
library for the useQuery
hook.
We're currently using react-query
(and previously useServerFetch
) to wrap & schedule promises for execution so that we can render React components with the data they need on the server. Rendering React components asynchronously isn't supported, so the need of these sorts of hooks for fetching data on the server before rendering definitely seems reasonable.
Some of the reasons we originally adopted react-query
was that it provided a more robust implementation for server-side requests that work with Suspense, that it works on the client, and that it comes with a built-in cache. However, some of the now-known drawbacks of adopting it as a library are that it doesn't support async fetches, and that the headers and other information about the response aren't being exposed.
One more drawback that the map+cache+batch prototype uncovered is that useQuery
absolutely won't allow for batching GraphQL requests, or delaying any async operation across hook invocations for that matter. react-query
includes its own scheduler to resolve promises as eagerly as possible and offers no configurability for deferring execution across hooks. If proper batching support were to be considered a priority, some of the options we have would be to either try to introduce batching support upstream in a library that wasn't designed for it, maintain our fork of react-query
with batching support, or return to writing our own implementation ร la useServerFetch
.
Although things sound dire, being in control of our own custom hook for server fetches (again) could be beneficial for us:
react-query
has it's own separate layer of caching that could stand to be consolidated with the rest of our caching framework for simplicity & debuggability.I think it could be interesting to entertain the idea of building our own server-side data-fetching hook. The problem has been solved before: react-frontload
is a tiny library that could server as inspiration for building one of these pseudo-synchronous hooks. Looking for feedback as to whether folks think about something like this!
All this being said, as we try to converge with RSC, it's unclear whether building a hook would be necessary for server fetches in the future, or if just a general data-fetching library will suffice.
Although data-fetching in an RSC world doesn't seem to have been finalized, all examples point to the ability to make use of asynchronous libraries for data-fetching in server components (eg. db.notes.get(props.id)
in the official RFC, and a new React server renderer that supports Suspense and waiting on asynchronous data on the server without double-rendering).
I'm relatively new to the world of React so I may be overlooking a couple things. Looking for some feedback on the general appetite for replacing useReactQuery
, and also hoping this issue sparks some discussion about our server-side data-fetching patterns, both for now and in the future with RSC.
The Video
object in the SF API includes alt
("A word or phrase to share the nature or contents of a media.") for accessibility.
While HTML's native img
tag has an alt
attribute for accessibility purposes, there's nothing like that for the video
tag (see MDN docs). We should figure out what the best way to communicate the alt text is within our Video
component, as we want to make sure we provide the best a11y as possible out-of-the-box.
Here's a potentially good starting point: https://stackoverflow.com/questions/32129240/html5-video-element-alternative-text
The SF API supports multiple languages, and it's possible to retrieve translated content with the Accept-Language
HTTP header. We don't currently have support for this, so we should add it!
Reference: https://shopify.dev/custom-storefronts/products/multiple-languages
Ideally our image component would support more than just images uploaded through the Shopify admin. We'd like to include "static images" such as those added through the public folder in order to get all of the performance best practices built into our image component.
Let's investigate how to do this!
This is a massive bummer.
We see completely different behavior for bundling the Hydrogen SDK during yarn dev
mode:
@shopify/hydrogen/client
in standalone mode, but not in monorepo mode.How can we fix this?
optimizeDep.exclude
Hydrogen SDKoptimizeDep.include
sub-dependencies, more filesYarn v1 doesn't allow us to use yarn link
since Hydrogen is namespaced with @shopify
.
Vite just switched to pnpm
. vitejs/vite#5060
yarn link
probably, get rid of dev
workflow and instead prompt devs working on Hydrogen to spin up a local instance that links the Hydrogen build into the repo.I get a the views stacked on top of each other, and sometimes they don't load at all client-side.
In a standalone app, sometimes things get to a state where you see this error in the console:
Uncaught SyntaxError: The requested module '/node_modules/react/index.js' does not provide an export named 'Component'
I do not know why this happens, what causes it, or how to fix it. It seems to be due to the way Vite bundles React's client dependencies (maybe react-is
whatever that dep is for).
The SF API's Online Store API exposes the online store's blog, articles, and comments. We don't currently have support for this in Hydrogen, so we should add support so that it's easy to retrieve blog information, articles, add comments, etc.
Express/etc have add-ons to help with fetching the body contents of an incoming request. We should tack this on to ServerComponentRequest
somewhere.
Maybe we can borrow useBody
from https://github.com/unjs/h3?
The useCartUI
hook throws an error when the context is not defined. This is great because it helps notify developers when it's being used incorrectly. However, the downside to this is components that make use of useCartUI
, but only optionally make use of the cartUI context value, end up with a hard dependency on the CartUIProvider
that it doesn't actually need.
A good example of this is the AddToCartButton
: it makes use of the useCartUI
hook to open the CartContainer
after an item is added to the cart. If the CartUIContext is not defined (ie: no CartUIProvider
), then it should just not open the CartContainer
. This could realistically happen if developers wish to make use of their own custom cart UI/UX. However, with the way the useCartUI
is set up now, even if the developers don't use the CartUIProvider
, they'd still need to include it in their app in order to use the AddToCartButton
, otherwise an error is thrown.
We could likely avoid this problem all together by just not throwing an error from the useCartUI
hook, but there definitely could be other alternatives!
More info in this comment. cc/ @jplhomer
The RawHtml
component previously had optional support for sanitizing HTML strings via the isomorphic-dompurify
library. We temporarily removed it since it wasn't working with the Worker runtime.
We should:
RawHtml
component and ensure it works in the Worker runtime. If not, remove it from the RawHtml
component and from the SDK's package.json
.Context on why we were optionally supporting sanitization:
"<p>Hello world</p>"
)script
tags and styling, potentially opening the door to security issues.RawHtml
component by passing a specific prop.Why wouldn't we want to support sanitization?
Personally I think it's still worth it to include the optional support since it provides good ergonomics and supports good practice.
https://shopify.dev/beta/hydrogen/framework/secrets
VITE_
and reference with import.meta.env
This issue is interesting, and perhaps there will be movement in this area: vitejs/vite#3176 (comment)
We're inconsistent in our code when it comes to IDs in our naming. Sometimes we keep ID uppercase (ex: variantID
), but othertimes it's lowercase (initialVariantId
).
I personally don't have a preference on whether we use ID
or Id
, as long as we stay consistent in the codebase. Which one should we use? ๐ค ๐คทโโ๏ธ
The Shop
object exposes the shop's privacy policy, refund policy, shipping policy, and terms of service. We should add support for these so that developers can easily use them.
From some brainstorming, I'm thinking:
Policy
context to query and hold the policies? It could have a corresponding hook usePolicies()
or usePolicy(<policyname>)
PrivacyPolicy
, RefundPolicy
, ShippingPolicy
, etc. components that automatically render a RawHtml
component with the policyWe autogenerate comments in the graphql-constants.ts
file which contains the values of the string constants. This helps developers consuming these fragments see what the value of the fragment string is by hovering over the constant in their IDE.
However, this file makes it into production code, and comments remain. This leads to a bigger bundle size. We should strip these out somehow when process.env.NODE_ENV == 'production'
.
React and other libraries do this with a fork in their codebase:
if (process.env.NODE_ENV == 'production') {
module.exports = require('./graphql-constants-without-comments.js');
} else {
module.exports = require('./graphql-constants-WITH-comments.js');
}
But how does this work in an ESM world? ๐ค
To repro, create a standalone Hydrogen app and:
yarn build
yarn serve
What is likely happening is that Vite is modulepreload
ing all these dependencies. At some point, when they are loaded from cache, they are loaded out of order so that React
is undefined.
Happens with:
And I'm not sure who to blame.
Let's split Hydrogen into two packages:
@shopify/hydrogen
: Includes entrypoints, Vite plugins, RSC/hydration things,@shopify/hydrogen-ui
: Includes React components and hooks, Server Components (CartServerProvider
, Localization
etc)TODO:
hydrogen-framework
without deleting it from hydrogen
dev
template to reference framework-specific packagehydrogen
See Shopify/hydrogen-archive#41 for an older discussion.
In my initial prototype, I had the following:
Opening this issue to have more discussion into these. Here are some initial thoughts from me:
h2 create
would be h2 create component
and h2 create app
and h2 create someOtherThing
. The default could be app.What do you want to call this app?
vs Enter app name
. I am not sure what is better here and makes me think we should consult a content strategist (cc @morganmccunn would that be possible?)One additional thought: It might be a good idea to sync with the folks designing the UX of the channel in the admin.
3 quick things to fix this
eslint-plugin-hydrogen
packagemodule.exports = {
extends: ['plugin:hydrogen/recommended'],
};
The classNames are generated properly, but no CSS makes it to the client.
Idea
Add a dev tools component that the user can render in the app. This could unlock a number of developer conveniences such as:
Other notes
User Experience over Developer Experience. Set this up so that is never increases our bundle size or slow downs our rendering time when not enabled.
References
More TBD
Part of #374
The official Server Components demo is built with the React experimental build using react-server-dom-webpack
. This package is Webpack-specific in some parts, like how client components are proxied on the server, and how client components are dynamically loaded in the browser.
However, lots of the code is not Webpack-specific! This means we can create a Vite (or even "rollup") version of the React package with relative ease.
This phase involves creating react-server-dom-vite
in the official React repo. We'll open a PR when we're ready and work with the core team to update, merge, and change certain parts as needed. Since it's an experimental build, we aren't on the hook for maintaining backwards compat or supporting existing users.
I am building out a cart feature using hydrogen (open PR here: https://github.com/Shopify/linkpop/pull/1298/files). when running tests using sewing-kit:
Test suite failed to run
Jest encountered an unexpected token
Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.
Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.
By default "node_modules" folder is ignored by transformers.
Details:
/Users/jonathanarnaldo/src/github.com/Shopify/linkpop/node_modules/@shopify/hydrogen/dist/esnext/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export * from './foundation/';
Steps to reproduce:
dev clone linkpop
git checkout feature/adds_hydrogen_cart
yarn test
web/components/ProductPopup/tests/ProductPopup.test.tsx
When running yarn dev
with Hydrogen where Vite 2.4.0 is used, you see these errors in the console:
12:34:22 PM [vite] new dependencies found: @shopify/h2-internal/client, updating...
> node_modules/node-fetch/lib/index.mjs:3:16: error: Could not read from file: /Users/joshlarson/src/github.com/jplhomer/hydrogen-app/url
3 โ import Url from 'url';
โต ~~~~~
> node_modules/node-fetch/lib/index.mjs:1:19: error: Could not read from file: /Users/joshlarson/src/github.com/jplhomer/hydrogen-app/stream
1 โ import Stream from 'stream';
โต ~~~~~~~~
> node_modules/node-fetch/lib/index.mjs:4:18: error: Could not read from file: /Users/joshlarson/src/github.com/jplhomer/hydrogen-app/https
4 โ import https from 'https';
โต ~~~~~~~
> node_modules/node-fetch/lib/index.mjs:5:17: error: Could not read from file: /Users/joshlarson/src/github.com/jplhomer/hydrogen-app/zlib
5 โ import zlib from 'zlib';
โต ~~~~~~
> node_modules/node-fetch/lib/index.mjs:2:17: error: Could not read from file: /Users/joshlarson/src/github.com/jplhomer/hydrogen-app/http
2 โ import http from 'http';
โต ~~~~~~
12:34:23 PM [vite] error while updating dependencies:
Error: Build failed with 5 errors:
node_modules/node-fetch/lib/index.mjs:1:19: error: Could not read from file: /Users/joshlarson/src/github.com/jplhomer/hydrogen-app/stream
node_modules/node-fetch/lib/index.mjs:2:17: error: Could not read from file: /Users/joshlarson/src/github.com/jplhomer/hydrogen-app/http
node_modules/node-fetch/lib/index.mjs:3:16: error: Could not read from file: /Users/joshlarson/src/github.com/jplhomer/hydrogen-app/url
node_modules/node-fetch/lib/index.mjs:4:18: error: Could not read from file: /Users/joshlarson/src/github.com/jplhomer/hydrogen-app/https
node_modules/node-fetch/lib/index.mjs:5:17: error: Could not read from file: /Users/joshlarson/src/github.com/jplhomer/hydrogen-app/zlib
at failureErrorWithLog (/Users/joshlarson/src/github.com/vitejs/vite/node_modules/esbuild/lib/main.js:1449:15)
at /Users/joshlarson/src/github.com/vitejs/vite/node_modules/esbuild/lib/main.js:1131:28
at runOnEndCallbacks (/Users/joshlarson/src/github.com/vitejs/vite/node_modules/esbuild/lib/main.js:921:63)
at buildResponseToResult (/Users/joshlarson/src/github.com/vitejs/vite/node_modules/esbuild/lib/main.js:1129:7)
at /Users/joshlarson/src/github.com/vitejs/vite/node_modules/esbuild/lib/main.js:1236:14
at /Users/joshlarson/src/github.com/vitejs/vite/node_modules/esbuild/lib/main.js:609:9
at handleIncomingPacket (/Users/joshlarson/src/github.com/vitejs/vite/node_modules/esbuild/lib/main.js:706:9)
at Socket.readFromStdout (/Users/joshlarson/src/github.com/vitejs/vite/node_modules/esbuild/lib/main.js:576:7)
at Socket.emit (node:events:378:20)
at addChunk (node:internal/streams/readable:313:12)
Vite is clearly struggling to load native Node.js internals like stream
and http
. This is not good!
I spent four hours debugging this to no avail. Here's what I found out:
Vite pre-optimizes dependencies that it knows about through your index.html
entrypoint, like entry-client.jsx
and everything in that module graph.
Once we hit our Hydrogen middleware and attempt to load entry-server.jsx
, it discovers a whole load of other dependencies. That's when you see a note in your terminal that it's going to optimize those dependencies and reload the page.
It is during that second optimization pass that shit breaks.
You can verify this by adding each one of the second-phase deps to the optimize.include
array in vite.config
. Once they are all added, and Vite pre-optimizes them, everything works just fine. (this is certainly an alternative fix, but it is terrible).
ssr
being passed to optimizeDeps
in Vite's source codeThis change was recently shipped as part of Vite 2.4.0: vitejs/vite#3933
Where the ssr
flag is passed through to the optimizer, the resolver, etc. This is technically accurate: we are using devServer.ssrLoadModule()
to fetch the entry-server.jsx
entrypoint.
Unfortunately, this behavior breaks in 2.4.0. I don't yet know why.
e.g. in a brand new Vite React project, where vite.config.js
looks like this:
import { defineConfig } from "vite";
import reactRefresh from "@vitejs/plugin-react-refresh";
import path from "path";
const myPlugin = {
name: "myplugin",
configureServer(server) {
server.middlewares.use(async (req, res, next) => {
const { render } = await server.ssrLoadModule(
path.resolve(__dirname, "./src/entry-server")
);
res.setHeader("content-type", "text/html");
return res.end(await render());
});
},
};
// https://vitejs.dev/config/
export default defineConfig({
plugins: [reactRefresh(), myPlugin],
});
And entry-server.jsx
looks like this:
import React from "react";
import { renderToString } from "react-dom/server";
import fetch from "node-fetch";
export async function render() {
const res = await fetch("https://shopify.com");
const html = await res.text();
return html + renderToString(<p>Hello</p>);
}
It works just fine ๐
reactServerComponentsShim()
but it didn't help.ssr: true
cause a side effect? is it in the resolveId
phase or the transform
phase?esbuild
- so it has to do with the options Vite is passing to esbuild itself.Very low priority, but could be a cool thing to have officially supported. I could see snippets for scaffolding common patterns for interacting with parts of our SDK, hooks, etc... This would serve very little purpose outside trying to give hydrogen/vscode power users the best possible developer experience.
Instead, we see a full page reload:
2:22:14 PM [vite] page reload src/components/ProductDetails.client.jsx
2:22:14 PM [vite] hmr update /src/index.css?direct
My guess is that as far as Vite knows, the component has no importers because it is loaded dynamically from our hydration syntax.
Not sure how to resolve this one, other than to teach Vite that it's OK to hot reload it.
When operating in a standalone Hydrogen app, you see this during setup:
This is because we recently implemented Shopify/hydrogen-archive#352 and a CartServerProvider
includes the CartProvider.client
as a Client Component. Layout.client
also references CartProvider
, and Vite dupes the two references into two separate chunks.
This leads to an context mismatch issue, as seen in the screenshot.
I do not know how to fix this. I think we need to teach Vite about the module graph within Client Components.
Additionally, this is troublesome to debug, because Vite behaves differently in Yarn monorepos vs standalone repos. See Shopify/hydrogen#34 for more.
Sometimes in a standalone app, we see this error in the Vite server console:
9:09:00 AM [vite] Internal server error: Cannot read property 'default' of null
at eval (/Users/joshlarson/Projects/site-h2/src/entry-server.jsx:9:84)
at async instantiateModule (/Users/joshlarson/Projects/site-h2/node_modules/vite/dist/node/chunks/dep-98dbe93b.js:73866:9)
It can't find a default entrypoint for entry-server.jsx
, which is trying to pull @shopify/hydrogen/entry-server
.
I do not know why this is happening, but it seems very related to the way Vite is bundling these files for SSR.
Just need to make sure this works on server and client.
Should also flag calling server hooks. This could be as simple as checking the import statements in the file and checking for server component imports.
We should have a rule to block rendering lifecycle (effects) on the server. In other words, look for server components that have useEffect() and useLayoutEffect() in them.
This will be helpful once we move the documentation in-repo.
The SF API 2021-07
version now supports locations and local pick up (see docs here).
We need to add support for this to Hydrogen.
Some brainstorming on what we need to support:
LocalizationProvider
), we'll likely want something like a LocationsProvider
for keeping track of the list of all locations and the location that the buyer prefers.ProductProvider
and related hook(s)At some point, we should switch to the exports
method of defining entrypoints into our Hydrogen NPM package. This effectively replaces the main
entrypoint + all the file-based "submodules" that litter the files
aray.
We can use conditional exports to specify CJS vs ESM.
I tried this once, but I ran into some issues RE: RSC hydration. We rely on Context to flag to the ClientMarker
that we're in hydration mode, but it's apparent that the Node.js dev server uses a separate build based on how the SSR entrypoint is loaded (CJS vs ESM). This sucks and also exposes a crack in our RSC logic.
Vite's SSR support is in beta. It works mostly. But there are some critical bugs and missing pieces.
See a discussion on Vite's repo about progress of SSR support
--bundle
flag (discussed here vitejs/vite#4230)
E.g. equivalent of Next.js's [...slug]
syntax.
This effectively sets exact={false}
on the Route.
Shipped in Shopify/hydrogen-archive#450, but useParams()
doesn't work to extract the full pathname (you have to use useLocation().pathname
instead).
Can we provide our own version of useParams()
that does support this?
For projects that don't want the batteries included approach, we should give them the option to just have the hydrogen specific eslint rules (our custom ones) which will play nice with any existing setup.
This issue documents our path to adopting the official React Server Components implementation in Hydrogen.
I've documented Vite-specific steps in an official Vite discussion here: vitejs/vite#4591
Why is this important? We want to eliminate our custom "fork" of Server Component logic as quickly as possible in order to adopt the official RSC version when it's ready and avoid hairy bugs.
Date | Status |
---|---|
Today | Done |
We've reverse-engineered a version of Server Components that works in Vite and with React 18 alpha.
This works for the most part and has unblocked devs and merchants from building on Hydrogen using patterns of Server Components. There are limitations and bugs that we'll need to advertise and support workarounds for early beta Hydrogen users.
Read more about how this phase came to be.
Date | Status |
---|---|
August 2021 | In progress |
The official Server Components demo is built with the React experimental build using react-server-dom-webpack
. This package is Webpack-specific in some parts, like how client components are proxied on the server, and how client components are dynamically loaded in the browser.
However, lots of the code is not Webpack-specific! This means we can create a Vite (or even "rollup") version of the React package with relative ease.
This phase involves creating react-server-dom-vite
in the official React repo. We'll open a PR when we're ready and work with the core team to update, merge, and change certain parts as needed. Since it's an experimental build, we aren't on the hook for maintaining backwards compat or supporting existing users.
Date | Status |
---|---|
September 2021 | Not started |
We should create a version of the official server components demo to prove out the functionality we built in the previous phase.
This can live in a Shopify repo, or in Facebook/React's org if they want.
Here's a starter repo: https://github.com/shopify/server-components-demo-vite
This will serve as a reference to both Shopify and to others hoping to implement React Server Components in Vite/Rollup.
Date | Status |
---|---|
September 2021 | Not started |
Once we have react-server-dom-vite
in the React repo, we should swap out our reverse-engineered implementation with the real version.
There are two caveats with this:
I'm particularly interested in the latter part, because we'll need to fix these bugs and blockers before RSC goes live. This is an opportunity to contribute fixes upstream in React and to the third-party packages we use.
For example: we might notice that React Router stops working. Or the way we're using Context in Hydrogen doesn't work in RSC.
Date | Status |
---|---|
December 2021* | Not started |
This could happen a number of ways:
shopify.config.js
. They might have to install the experimental version of React, which we could prompt from them.Most of these depend on the official React roadmap and how quickly RSC gets shipped into stable.
* Very, very optimistic estimate for our Hydrogen roadmap. It could be much longer.
We disabled some a11y checks to avoid massive code churn in Shopify/hydrogen-archive#328 but we'll want to reenable these as per this discussion.
jsx-a11y/label-has-for
https://github.com/Shopify/hydrogen-archive/pull/412jsx-a11y/control-has-associated-label
https://github.com/Shopify/hydrogen-archive/pull/412jsx-a11y/click-events-have-key-events
jsx-a11y/no-noninteractive-element-interactions
Today, in order to use a Hydrogen-supplied Client Component in a Hydrogen app's Server Component, you have to re-export the component from a ClientComponent in your project:
// pages/index.server.jsx
import Link from '../components/Link.client';
export default function Page() {
return <Link to="..." />
}
// components/Link.client.jsx
import {Link} from '@shopify/hydrogen/client';
export default Link;
This is a bummer. It is an artifact of the way we reverse engineered Server Components for Hydrogen.
// pages/index.server.jsx
import Link from '@shopify/hydrogen/Link.client'
// or:
import {Link} from '@shopify/hydrogen'
export default function Page() {
return <Link to="..." />
}
exports
to expose all Hydrogen SDK client components in a way that supports the /\.client$/
heuristic. See Shopify/hydrogen-archive#437react-server-dom-webpack
does for real RSCPR Shopify/hydrogen-archive#535 introduced the numCartLines
variable to the CartFragment and all Cart-related operations (mutations and queries). The numCartLines
was also added as a prop to CartProvider
/CartServerProvider
, so developers could customize this value for their entire application.
For further customization ability, we should look into adding support for customizing the numCartLines
for each cart callback. I haven't investigated this fully, but I'm imagining something like:
const createCart = useCartCreateCallback({numCartLines: X} );
or
const createCart = useCartCreateCallback();
...
createCart(<cartinput>, {numCartLines: X)
This would likely have a knock-on effect where we may have to support numCartLines
as a prop to components like AddToCartButton
/CartLineQuantityAdjustButton
, so I don't know at the moment if this is a great approach necessarily. I'll leave that up to the person investigating this issue ๐ ๐คทโโ๏ธ
When we fetch hydration server responses in Cache.client
, we cache them in a simple Map
. This is fine, but we need to be able to clear this cache:
N seconds
) because you'd want to see if a product is sold outserverState
, e.g. maybe you updated a cart or customer data, and you need it updated in your entire tree.Resources:
refresh
helper after a note has been updated: https://github.com/reactjs/server-components-demo/blob/main/src/NoteEditor.client.js#L58Occasionally in a standalone app, this error appears in the Vite console:
Error: Invariant failed: You should not use <Switch> outside a <Router>
at invariant (/Users/scottdixon/src/switch/node_modules/tiny-invariant/dist/tiny-invariant.cjs.js:13:11)
at /Users/scottdixon/src/switch/node_modules/react-router/cjs/react-router.js:675:19
at renderContextConsumer (/Users/scottdixon/src/switch/node_modules/react-dom/cjs/react-dom-unstable-fizz.node.development.js:5392:21)
at renderElement (/Users/scottdixon/src/switch/node_modules/react-dom/cjs/react-dom-unstable-fizz.node.development.js:5511:11)
at renderNodeDestructive (/Users/scottdixon/src/switch/node_modules/react-dom/cjs/react-dom-unstable-fizz.node.development.js:5577:11)
at finishClassComponent (/Users/scottdixon/src/switch/node_modules/react-dom/cjs/react-dom-unstable-fizz.node.development.js:5208:3)
at renderClassComponent (/Users/scottdixon/src/switch/node_modules/react-dom/cjs/react-dom-unstable-fizz.node.development.js:5216:3)
at renderElement (/Users/scottdixon/src/switch/node_modules/react-dom/cjs/react-dom-unstable-fizz.node.development.js:5430:7)
at renderNodeDestructive (/Users/scottdixon/src/switch/node_modules/react-dom/cjs/react-dom-unstable-fizz.node.development.js:5577:11)
at renderNode (/Users/scottdixon/src/switch/node_modules/react-dom/cjs/react-dom-unstable-fizz.node.development.js:5719:12)
Can't consistently reproduce it.
Blocked by Shopify/hydrogen#40
Part of Shopify/hydrogen#35
We should create a version of the official server components demo to prove out the functionality we built in the previous phase.
This can live in a Shopify repo, or in Facebook/React's org if they want.
This will serve as a reference to both Shopify and to others hoping to implement React Server Components in Vite/Rollup.
Blocked by Shopify/hydrogen#40
Part of Shopify/hydrogen#35
Once we have react-server-dom-vite
in the React repo, we should swap out our reverse-engineered implementation with the real version.
There are two caveats with this:
I'm particularly interested in the latter part, because we'll need to fix these bugs and blockers before RSC goes live. This is an opportunity to contribute fixes upstream in React and to the third-party packages we use.
For example: we might notice that React Router stops working. Or the way we're using Context in Hydrogen doesn't work in RSC.
Based on a brief conversation with @iaserrat this should be a simple github action that we scaffold out for the user.
This issue picks up where Shopify/hydrogen#328 left off by providing users with an opinionated lint setup (using ESlint) that maps to a broader conformance story.
/packages/eslint-plugin
.eslintrc
to this package and export a recommended
config (more configs will come later)no-use-state
)This is an incomplete list, but should get us on a good foundation that we can build on (or have others build on) over time.
Questions
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.