Creating campaign pages

In Sanity and Shopify with Hydrogen you setup the basics to connect Sanity, Shopify and a Hydrogen front end. With these systems now all working together it's time to create rich experiences.
In the following exercises you'll create a campaign page for a specific set of products. This is the sort of editorial work your content creators are likely going to need to do on a regular basis.
With Sanity, you can prepare the building blocks they need to instantly create new landing pages while benefiting from referencing up to date external content like product data.
The shopify Studio template you've used comes with a number of pre-configured blocks which you could add to or modify. They've been made available to this portable text field.
In your Sanity Studio, take a look at the portableTextType.ts schema type file. It is an array type field that first contains a block type – and then multiple other object types. That's where this list was configured.
Looking at page documents in the Studio, the body field is just an array type field. But, since one of its fields is a block type field, Sanity Studio presents renders it with the Portable Text editor – instead of the default array type UI.
The Portable Text editor allows you to write rich text and block content.
While the data is the same – an array of objects – no matter which editor you use, for this module we're making the editorial decision that page content will only ever be block content. For this the default array editor is simpler to use.
Let's copy the block types from this portable text field and replace the body field in page documents.
body field in your page type schemadefineField({ name: 'body', type: 'array', group: 'editorial', of: [ defineArrayMember({ type: 'accordion' }), defineArrayMember({ type: 'callout' }), defineArrayMember({ type: 'grid' }), defineArrayMember({ type: 'images' }), defineArrayMember({ type: 'imageWithProductHotspots', title: 'Image with Hotspots' }), defineArrayMember({ type: 'instagram' }), defineArrayMember({ type: 'products' }), ]}),The body field should now look like this:
You can start creating content with these blocks, but most importantly, you'll need to update your Hydrogen front end to render them.
For a smoother developer experience in the following exercises, generate Types from your Studio schema and copy the definitions into the Hydrogen app.
Inside your Studio project:
npx sanity@latest schema extracttypegen generate is run in your Studio{ "path": "../sanity-and-hydrogen/app/sanity/queries.ts", "schema": "schema.json", "generates": "../sanity-and-hydrogen/app/sanity/sanity.types.ts"}npx sanity@latest typegen generateYou should now have a file sanity.types.ts inside your Hydrogen app.
Now in your Hydrogen app, you'll need to setup a route to render page type documents.
import groq from 'groq';
export const PAGE_QUERY = groq`*[_type == "page" && slug.current == $slug][0]`import {json, type LoaderFunctionArgs} from '@shopify/remix-oxygen';import {useLoaderData} from '@remix-run/react';import type {PAGE_QUERYResult} from '~/sanity/sanity.types';import {PAGE_QUERY} from '~/sanity/queries';
const BLOCKS: Record<string, (props: any) => JSX.Element | null> = { _unknown: (props: any) => <pre>{JSON.stringify(props, null, 2)}</pre>,};
export async function loader({params, context: {sanity}}: LoaderFunctionArgs) { const query = PAGE_QUERY; const initial = await sanity.loadQuery<PAGE_QUERYResult>(query, params);
if (!initial.data) { throw new Response('Not found', {status: 404}); }
return json({initial});}
export default function Page() { const {initial} = useLoaderData<typeof loader>(); const page = initial?.data;
return Array.isArray(page?.body) ? ( <main> {page.body.map((block) => block._type in BLOCKS ? BLOCKS[block._type]({key: block._key, ...block}) : BLOCKS._unknown({key: block._key, ...block}), )} </main> ) : null;}This route renders each array field item as a unique component. If a matching component is not found, the item's content is stringified and rendered to the page.
Back in your Sanity Studio, create a page
slugbody fieldVisit http://localhost:3000/the-blue-collection and you should see a page something like this:
Now, let's style this "accordion" block.