• Stars
    star
    312
  • Rank 129,713 (Top 3 %)
  • Language
    TypeScript
  • Created over 2 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A starter for Hydrogen + Sanity projects

AKVA - An example storefront powered by Sanity + Hydrogen

This demo is compatible with @shopify/hydrogen >= 2023.1.0 built on Remix.

For the legacy Hydrogen v1 template, please refer to the hydrogen-v1 branch.

Demo | Sanity Studio | Sanity Connect for Shopify

About

AKVA is our customized Hydrogen starter that presents a real-world example of how Sanity and Structured Content can elevate your custom Shopify storefronts.

It's designed to be used alongside our pre-configured Studio and Sanity Connect for Shopify, which syncs products and collections from your Shopify storefront to your Sanity dataset.

This starter showcases a few patterns you can adopt when creating your own custom storefronts. Use Sanity and Hydrogen to delight customers with rich, shoppable editorial experiences that best tell your story.

Features

View the feature gallery

This TypeScript demo adopts many of Hydrogen's framework conventions and third-party libraries. If you've used Hydrogen then you should hopefully feel at home here.

Fetching Sanity data

This demo comes preconfigured to use hydrogen-sanity, which adds a Sanity client to the Remix context. This enables you to fetch content from Sanity in Remix loaders and actions.

In addition to this, we've created a query utility, which uses Hydrogen's caching strategies to reduce the number of calls to Sanity's API. If no strategy is provided to the cache option, then the Hydrogen CacheLong() strategy will be used by default.

It's possible to make calls to the Sanity API either with query:

import {json, type LoaderArgs} from '@shopify/remix-oxygen';
import type {SanityProductPage} from '~/lib/sanity';

const QUERY = `*[_type == 'product' && slug.current == $slug]`;

export async function loader({params, context}: LoaderArgs) {
  const cache = context.storefront.CacheLong();

  const sanityContent = await context.sanity.query<SanityProductPage>({
    query: QUERY,
    params: {
      slug: params.handle,
    },
    cache,
  });

  return json({sanityContent});
}

or directly with the Sanity client:

// <root>/app/routes/($lang).products.$handle.tsx
import {useLoaderData} from '@remix-run/react';
import {json, type LoaderArgs} from '@shopify/remix-oxygen';
import type {SanityProductPage} from '~/lib/sanity';

const QUERY = `*[_type == 'product' && slug.current == $slug]`;

export async function loader({params, context}: LoaderArgs) {
  const sanityContent = await context.sanity.client.fetch<SanityProductPage>(
    QUERY,
    {
      slug: params.handle,
    },
  );

  return json({sanityContent});
}
export default function Product() {
  const {sanityContent} = useLoaderData<typeof loader>();

  // ...
}

This uses our official @sanity/client library, so it supports all the methods you would expect to interact with Sanity API's

You can also use the defer and Await utilities from Remix to prioritize critical data:

// <root>/app/routes/($lang).products.$handle.tsx
import {Suspense} from 'react';
import {Await, useLoaderData} from '@remix-run/react';
import {defer, type LoaderArgs} from '@shopify/remix-oxygen';
import type {SanityProductPage, LessImportant} from '~/lib/sanity';

const QUERY = `*[_type == 'product' && slug.current == $slug]`;
const ANOTHER_QUERY = `*[references($id)]`;

export async function loader({params, context}: LoaderArgs) {
  /* Await the important content here */
  const sanityContent = await context.sanity.query<SanityProductPage>({
    query: QUERY,
    params: {
      slug: params.handle,
    },
  });

  /* This can wait - so don't await it - keep it as a promise */
  const moreSanityContent = context.sanity.query<LessImportant>({
    query: ANOTHER_QUERY,
    params: {
      id: sanityContent._id,
    },
  });

  return defer({sanityContent});
}
export default function Product() {
  const {sanityContent, moreSanityContent} = useLoaderData<typeof loader>();

  return (
    <div>
      <Content value={sanityContent} />
      {/* Wrap promises in a Suspense fallback and await them */}
      <Suspense fallback={<Spinner />}>
        <Await resolve={moreSanityContent}>
          {(content) => <MoreContent value={content} />}
        </Await>
      </Suspense>
    </div>
  );
}

Live Preview

In addition to providing a Sanity Client, hydrogen-sanity can utilize Sanity's realtime content platform to give editors live-as-you-type previewing of their content. That way they can see, in context, how their changes will appear directly in the storefront.

You can read more about configuration in the hydrogen-sanity documentation.

This demo is set up with an example of live preview on the ($lang)._index.tsx route.

Opinions

We've taken the following opinions on how we've approached this demo.

Shopify is the source of truth for non-editorial content
  • For products, this includes titles, handles, variant images and product options.
  • For collections, this includes titles and collection images.
Shopify data stored in our Sanity dataset is used to improve the editor experience
  • This allows us to display things like product status, prices and even inventory levels right in our Sanity Studio.
  • Our application always fetches from Shopify's Storefront API at runtime to ensure we have the freshest data possible, especially important when dealing with fast-moving inventory.
Collections are managed entirely by Shopify
  • Shopify is used to handle collection rules and sort orders.
Product options are customized in Sanity
  • Data added to specific product options (for example, associating a hex value with the color 'Red', or a string value with the Poster size 'A2') is done in Sanity.
  • We treat this quite simply and manage these in a dedicated field within the Settings section of our studio. We also make sure to query this field whenever querying products in our Sanity dataset.
  • This could alternatively be managed with Shopify's metatags.
We don't surface Shopify HTML descriptions and metatags
  • For this demo, Shopify tags are used purely as a non-visual organizational tool (to drive automated collections) and we use Portable Text over Shopify's description HTML field. However, Hydrogen makes it very easy to surface these in your application if needed.
Non-product (regular) pages are managed entirely by Sanity
  • Shopify pages and blog posts (associated with the Online Store) channel aren't used in this demo. A dedicated page document type in Sanity has been created for this purpose.
We query our Sanity dataset when building sitemap.xml entries
  • We use Sanity as the source of truth when determining whether a product or collection page is visible.
  • This gives us the flexibility to add custom logic to control whether certain pages should be visible or not. For example, if you wanted to hide product pages within a specific date range, or hide collections that didn't have any editorial modules assigned to them.

Analytics

We've set up basic Shopify Analytics on this demo. The hasUserConsent boolean in <root>/app/root.tsx is set to true - you'll likely need to set up user consent based on the relevant regulations for your storefront.

Getting started

Requirements:

  • Node.js version 16.14.0 or higher
  • npm (or your package manager of choice, such as yarn or pnpm)

Getting Started

  1. Create a .env file, based on the .env.template file.

  2. Install dependencies and start the development server

    npm i
    npm run dev
  3. Visit the development environment running at http://localhost:3000.

For information on running production builds and deployment, see the Hydrogen documentation.

License

This repository is published under the MIT license.

More Repositories

1

sanity

Sanity Studio – Rapidly configure content workspaces powered by structured content
TypeScript
4,364
star
2

litter

Litter is a pretty printer library for Go data structures to aid in debugging and testing.
Go
1,437
star
3

next-sanity

Sanity.io toolkit for Next.js
TypeScript
667
star
4

GROQ

Specification for GROQ - The Query Language for JSON
JavaScript
368
star
5

nextjs-blog-cms-sanity-v3

A Next.js Blog with a Native Authoring Experience
TypeScript
347
star
6

example-company-website-gatsby-sanity-combo

This is an example company website using Gatsby and Sanity in combination.
JavaScript
270
star
7

groq-js

JavaScript implementation of GROQ, the query language for JSON
TypeScript
250
star
8

mendoza

Differ for structured documents (JSON)
Go
234
star
9

example-frontend-next-js

An example of a Sanity powered frontend using Next.js
JavaScript
212
star
10

gatsby-source-sanity

Gatsby source plugin for building websites using Sanity.io as a backend.
TypeScript
195
star
11

groq-cli

Run GROQ in your command line
JavaScript
193
star
12

template-nextjs-personal-website

A Next.js Personal Website with a Native Authoring Experience
TypeScript
165
star
13

block-content-to-react

Deprecated in favor of @portabletext/react
JavaScript
162
star
14

sanity-recipes

A collection of recipies / snippets / frequently asked questions about Sanity.io
JavaScript
159
star
15

sanity-plugin-media

Asset management plugin for Sanity
TypeScript
144
star
16

sanity-template-nextjs-landing-pages

A Sanity powered landing page builder in Next.js for https://sanity.io/create
JavaScript
142
star
17

squizzy

Quizzes with Squizzy the Squid!
JavaScript
139
star
18

sanity-shopify-studio

An example Sanity Studio configured for headless Shopify projects.
TypeScript
134
star
19

tutorial-sanity-blog-react-next

Front-end code for the Sanity, React, Next.js tutorial.
TypeScript
133
star
20

document-internationalization

Create unique translations of a document based on its language, joined by a shared reference document
TypeScript
118
star
21

sanity-template-nextjs-clean

A clean Next.js template with a native authoring experience
TypeScript
117
star
22

ui

UI building blocks for Sanity.
TypeScript
117
star
23

sanity-template-nextjs-app-router-personal-website

A Next.js Personal Website with a Native Authoring Experience. Uses app router.
113
star
24

sanity-template-kitchen-sink

A collection of demo examples
JavaScript
103
star
25

example-ecommerce-snipcart-vue

The Transglobal Candy Store: Sample front-end for the Sanity.io e-commerce schema with vue.js, nuxt.js, and snipcart
Vue
100
star
26

sanity-template-gatsby-blog

A Sanity powered Gatsby blog for https://www.sanity.io/create
JavaScript
99
star
27

preview-kit

General purpose live previews, like next-sanity
TypeScript
91
star
28

sanity-template-nextjs-blog-comments

JavaScript
83
star
29

sanity-template-nextjs-ecommerce

CSS
76
star
30

example-frontend-vue-js

An example of a Sanity powered frontend using Vue.js
Vue
72
star
31

community-studio

Sanity Community Management Studio
TypeScript
72
star
32

sanity-template-astro-clean

Clean starter template with Astro
Astro
70
star
33

sanity-template-gatsby-portfolio

A Gatsby portfolio site powered by Sanity for https://www.sanity.io/create
JavaScript
70
star
34

content-source-maps

Specification for the Content Source Maps standard
69
star
35

orderable-document-list

Drag-and-drop Document Ordering without leaving the Editing surface
TypeScript
67
star
36

plugin-kit

Enhanced Sanity.io plugin development experience.
TypeScript
64
star
37

client

JavaScript client for retrieving, creating and patching data from Sanity.io
TypeScript
61
star
38

sanity-algolia

Utilities for indexing Sanity documents in Algolia
TypeScript
61
star
39

sanity-plugin-graph-view

A tool for Sanity Studio to graph your content and see changes in real-time.
TypeScript
49
star
40

github-action-sanity

Dockerfile
49
star
41

sanity-astro

Astro
49
star
42

next-recipe-app

CSS
47
star
43

sanity-template-nuxt-events

A Sanity powered Conference site in Vue / Nuxt for https://www.sanity.io/create
Vue
46
star
44

startup-starter-kit

The Structured Content Startup Starter Kit
JavaScript
45
star
45

demo-custom-workflow

A demonstration of a custom content publishing workflow using Sanity.
HTML
44
star
46

sanity-template-sapper-blog

JavaScript
44
star
47

sanity-plugin-iframe-pane

Display any URL in a View Pane, along with helpful buttons to copy the URL, display a mobile size, reload the iframe or open in a new tab
TypeScript
44
star
48

netlify-form-sanity

How to use Netlify Forms and Functions to submit data to Sanity.io
HTML
44
star
49

demo-course-platform

An example Studio and Front End demonstrating different strategies for localization with Sanity.io
TypeScript
43
star
50

image-url

Tools to generate image urls from Sanity content
TypeScript
43
star
51

sanity-plugin-markdown

Markdown support in the Sanity Studio
TypeScript
42
star
52

sanity-plugin-mux-input

An input component that integrates Sanity Studio with MUX.com video encoding/hosting service.
TypeScript
41
star
53

gatsby-portfolio-preview-poc

Gatsby Portfolio Preview POC
JavaScript
40
star
54

groq-store

In-memory GROQ store. Streams all available documents from Sanity into an in-memory database for local querying.
TypeScript
40
star
55

demo-marketing-site-nextjs

TypeScript
39
star
56

sanity-template-nextjs-event-starter

Fully customizable starter kit for your virtual event.
TypeScript
39
star
57

sanity-plugin-seo-pane

Run Yoast's SEO review tools using Sanity data, inside a List View Pane.
TypeScript
38
star
58

vscode-sanity

Visual Studio Code extension for developing applications powered by Sanity.io
TypeScript
38
star
59

example-app-react-native

Sanity + React Native app example
JavaScript
38
star
60

sanity-template-eleventy-blog

Minimal blog with Eleventy and Sanity
JavaScript
37
star
61

hierarchical-document-list

Plugin for editing hierarchical references in the Sanity studio.
TypeScript
37
star
62

sanity-studio-secrets

Hooks and chrome for handling secrets in plugins
TypeScript
36
star
63

react-rx

React + RxJS = <3
TypeScript
36
star
64

sanity-plugin-internationalized-array

A plugin to register array fields with a custom input component to store field values in multiple languages, queryable by using the language ID as an array `_key`.
TypeScript
36
star
65

mendoza-js

Mendoza decoder in TypeScript
TypeScript
35
star
66

themer

Experimental, creates Studio v3 themes
TypeScript
34
star
67

webhook-toolkit

Toolkit for dealing with GROQ-powered webhooks delivered by Sanity.io
TypeScript
33
star
68

sanity-template-sveltekit-clean

Clean starter template with SvelteKit
CSS
32
star
69

sanity-template-svelte-kit

A minimal, fully customizable SvelteKit front-end powered by Sanity.io data.
JavaScript
32
star
70

swift-sanity

Swift
31
star
71

sanity-plugin-dashboard-widget-vercel

TypeScript
31
star
72

hydrogen-sanity

TypeScript
29
star
73

sanity-plugin-dashboard-widget-netlify

Sanity Studio Dashboard Widget for triggering Netlify builds
TypeScript
29
star
74

sanity-template-nuxt-clean

Clean starter template with Nuxt
Vue
29
star
75

sanity-template-vercel-visual-editing

TypeScript
29
star
76

cross-dataset-duplicator

Empower content editors to migrate Documents and Assets between Sanity Projects and Datasets from inside Sanity Studio.
TypeScript
29
star
77

sanity-php

PHP library for retrieving, creating and patching data from Sanity.io
PHP
28
star
78

sanity-plugin-scheduled-publishing

Schedule documents for future publishing
TypeScript
28
star
79

table

Table schema type and input component for Sanity Studio
TypeScript
28
star
80

get-it

Composable HTTP request library for node and browsers
TypeScript
26
star
81

contentful-to-sanity

Migrate from Contentful to Sanity
TypeScript
26
star
82

sanity-template-gridsome-blog

A Sanity powered Gridsome blog for sanity.io/create
JavaScript
25
star
83

visual-editing

TypeScript
25
star
84

asset-utils

Reusable utility functions for dealing with image and file assets in Sanity
TypeScript
24
star
85

create-react-app-blog

JavaScript
22
star
86

pkg-utils

Simple utilities for modern npm packages.
TypeScript
22
star
87

jsonwebtoken-esm

jsonwebtoken wrapper that provides esm support
JavaScript
21
star
88

sanity-mux-player

Play videos in the frontend uploaded with the MUX Sanity plugin
JavaScript
21
star
89

sanity-plugin-hotspot-array

A configurable Custom Input for Arrays that will add and update items by clicking on an Image
TypeScript
21
star
90

sanity-nextjs-vercel-example

A bare bones example of a Vercel-deployable project with a Next.js frontend and a Sanity Studio on /studio
JavaScript
21
star
91

block-content-to-html

Deprecated in favor of @portabletext/to-html
JavaScript
21
star
92

demo-media-site-nextjs

A demo template for a content-driven site with longform content and newsletter capability
TypeScript
20
star
93

block-content-to-markdown

Transform Sanity block content to Markdown
JavaScript
20
star
94

demo-ecommerce

TypeScript
20
star
95

dashboard

Tool for rendering dashboard widgets
TypeScript
20
star
96

structured-content-2022

TypeScript
20
star
97

locales

A repository of user-contributed locale/language packs for Sanity Studio
TypeScript
20
star
98

gridsome-source-sanity

Sanity source plugin for Gridsome
JavaScript
19
star
99

sanity-plugin-shopify-assets

TypeScript
19
star
100

sanity-template-remix-clean

Clean starter template with Remix
TypeScript
19
star