diff --git a/app/data/index.ts b/app/data/index.ts index 761ec23e29..10c3300a97 100644 --- a/app/data/index.ts +++ b/app/data/index.ts @@ -21,6 +21,7 @@ import type { CustomerUpdateInput, CustomerUpdatePayload, UserError, + Page, } from "@shopify/hydrogen-ui-alpha/storefront-api-types"; import { getPublicTokenHeaders, @@ -1035,6 +1036,38 @@ export async function getArticle(variables: { return data.blog.articleByHandle; } +const PAGE_QUERY = `#graphql + query PageDetails($languageCode: LanguageCode, $handle: String!) + @inContext(language: $languageCode) { + page(handle: $handle) { + id + title + body + seo { + description + title + } + } + } +`; + +export async function getPageData(variables: { + language: LanguageCode; + handle: string; +}) { + const { data } = await getStorefrontData<{ page: Page }>({ + query: PAGE_QUERY, + variables, + }); + + invariant(data, "No data returned from Shopify API"); + if (!data.page) { + throw new Response("Not found", { status: 404 }); + } + + return data.page; +} + const NOT_FOUND_QUERY = `#graphql ${PRODUCT_CARD_FRAGMENT} query homepage($country: CountryCode, $language: LanguageCode) diff --git a/app/routes/pages/$pageHandle.tsx b/app/routes/pages/$pageHandle.tsx new file mode 100644 index 0000000000..12e957d297 --- /dev/null +++ b/app/routes/pages/$pageHandle.tsx @@ -0,0 +1,57 @@ +import { + json, + LoaderArgs, + MetaFunction, + SerializeFrom, +} from "@remix-run/cloudflare"; +import { useLoaderData } from "@remix-run/react"; +import invariant from "tiny-invariant"; +import { PageHeader } from "~/components"; +import { getPageData } from "~/data"; + +export async function loader({ params }: LoaderArgs) { + // TODO figure out localization + const languageCode = "EN"; + + invariant(params.pageHandle, "Missing page handle"); + + const page = await getPageData({ + handle: params.pageHandle, + language: languageCode, + }); + + return json( + { page }, + { + headers: { + // TODO cacheLong() + }, + } + ); +} + +export const meta: MetaFunction = ({ + data, +}: { + data: SerializeFrom | undefined; +}) => { + return { + title: data?.page?.seo?.title ?? "Page", + description: data?.page?.seo?.description, + }; +}; + +export default function Page() { + const { page } = useLoaderData(); + + return ( + <> + +
+ + + ); +}