Tip: Looking for releasing instructions?
Requirements:
- Node.js version 16.14.0 or higher
- Yarn
git clone [email protected]:Shopify/hydrogen.git
npm install
npm run build
To develop against a template, open a new terminal window or tab and choose from the available templates:
- templates/demo-store
- templates/hello-world
cd templates/demo-store
npm run dev
Visit the dev environment at http://localhost:3000.
To make changes to the Demo Store template, edit the files in templates/demo-store
.
To modify Hydrogen framework, components, and hooks, edit the files in packages/hydrogen
.
Hydrogen is a monorepo built with Turbo. It consists of several key packages:
templates
: Full working implementations of a Hydrogen storefront (including the Demo Store template)packages/hydrogen
: The hooks, components, and utilities provided by Hydrogenpackages/remix-oxygen
: A Remix runtime adapter for Oxygen
Hydrogen uses ESLint for linting and Prettier for code formatting.
Yorkie is used to install a Git precommit hook, which lints and formats staged commits automatically.
To manually typecheck, lint, and format:
npm run typecheck
npm run lint
npm run format
Hydrogen follows common React naming conventions for filenames, component names, classes, constants, and more.
- For component filenames and class names, always use
PascalCase
. - For non-component filenames, always use fully lowercase
kebab-case
. - For test filenames, append
.test
before the file extension. - When declaring instances of components, always use
camelCase
. - When declaring exported constants, always use
SCREAMING_SNAKE_CASE
.
✅ Valid | 🚫 Invalid | |
---|---|---|
Component filenames: | ProductTitle.tsx ProductTitle.tsx |
productTitle.tsx product_title.tsx product-title.tsx |
Non-component filenames: | client.ts handle-event.ts |
Client.ts handleEvent.ts handle_event.ts |
Test filenames: | ExternalVideo.test.tsx |
ExternalVideo-test.tsx ExternalVideo_test.tsx ExternalVideoTest.tsx |
Component classes: | <AddToCartButton /> |
<addToCartButton /> |
Component instances: | const cartSelector = <CartSelector /> |
const CartSelector = <CartSelector /> const cart_selector = <CartSelector /> |
Exported constants: | export const CART_COOKIE_TTL_DAYS = 14; |
export const CartCookieTTLDays = 14; export const cart_cookie_ttl_days = 14; |
If you are contributing a user-facing or noteworthy change to Hydrogen that should be added to the changelog, you should include a changeset with your PR.
To add a changeset, run this script locally:
npm run changeset add
Follow the prompts to select which package(s) are affected by your change, and whether the change is a major, minor or patch change. This will create a file in the .changesets
directory of the repo. This change should be committed and included with your PR.
Considerations:
- You can use markdown in your changeset to include code examples, headings, and more. However, please use plain text for the first line of your changeset. The formatting of the GitHub release notes does not support headings as the first line of the changeset.
- When selecting packages for the changesets, only select packages which are published. Do not include private packages, as it will cause the build to fail. Hopefully these are removed from the list of options in a future Changesets release.
When merging PRs, please select the Squash and Merge option, which consolidates all the changes from the PR into a single commit. This helps reduce the commit noise in our Git repository.
If you are building or making changes to a component, be sure to read What are headless components? and How to build headless components.
You can directly import the TypeScript type from /packages/src/storefront-api-types.ts
which will match the full shape of the object from the Storefront API. If you're working on a component, you're not guarnateed to get an object in the exact shape as that type, so wrap it in PartialDeep
which is imported from type-fest
. This will also force the component to be more defensive in handling optional properties.
To update the types, follow the steps below, excluding the parts where you update the version.
We use graphql-codegen
to automatically generate types for all of the Storefront API objects for a given version, and that version can be found in the codegen.yml
file.
In order to update the supported Storefront API version:
- Update the Schema URL and the header comment in
codegen.yml
- Run
yarn graphql-types
- Fix any TypeScript errors that now appear
- One fast way to find them is to run
yarn build
from the monorepo root and see what TypeScript errors show up - Another way is to clear the test cache with
yarn test --clearCache && yarn test
- One fast way to find them is to run
For context, updating the codegen.yml
file and running the script does the following:
- Automatically hits the Storefront API, and use an introspection query to get the latest info
- Uses the results of that query to generate a new
graphql.schema.json
(which is a local representation of the Storefront API) - Generates / updates the new types in
/packages/hydrogen/src/storefront-api-types.ts
based on thegraphql.schema.json
Hydrogen is tested with unit tests for components, hooks and utilities. It is also tested with a suite of end-to-end tests inspired by Vite's playground tests.
Run unit tests with:
npm run test
# Optionally watch for changes
yarn test:watch
Tests that fail only in CI can be difficult and time-consuming to debug. If you find yourself in this situation, you can use tmate to pause the Github Action on a given step and ssh
into the container. Once in the container you can use vim
, inspect the file system and try determining what might be diverging from running tests on your local computer and leading to the failure.
- Add the following
step
in your Github Actions workflow:
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
- Commit and push your changes to Github.
- The testing Github Action will run automatically and you will see it paused with both a Web Shell address and SSH address.
- Copy and paste the SSH address into your terminal.