Skip to content

Instantly share code, notes, and snippets.

@beamercola
Last active September 3, 2022 18:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save beamercola/fb317e74bfa4c12087032d9f9308413a to your computer and use it in GitHub Desktop.
Save beamercola/fb317e74bfa4c12087032d9f9308413a to your computer and use it in GitHub Desktop.
import * as React from "react"
import { GetStaticPaths, GetStaticProps } from "next"
import Error from "next/error"
import { CartProvider } from "@shopify/hydrogen"
import HydrogenProvider from "~/Hydrogen/Provider"
import { PLASMIC } from "plasmic.client"
import { getProductHandles } from "shopify.client"
import {
PlasmicComponent,
ComponentRenderData,
extractPlasmicQueryData,
PlasmicRootProvider,
} from "@plasmicapp/loader-nextjs"
/**
* Use fetchPages() to fetch list of pages that have been created in Plasmic
*/
export const getStaticPaths: GetStaticPaths = async () => {
const pages = await PLASMIC.fetchPages()
const products = await getProductHandles()
return {
paths: [
...pages.map(page => ({
params: { slug: page.path.substring(1).split("/") },
})),
...products.map(slug => ({
params: { slug: ["products", slug] },
})),
],
fallback: "blocking",
}
}
/**
* For each page, pre-fetch the data we need to render it
*/
export const getStaticProps: GetStaticProps = async context => {
const { slug } = context.params ?? {}
// Convert the slug param into a path string
const plasmicPath =
typeof slug === "string"
? slug
: Array.isArray(slug)
? `/${slug.join("/")}`
: "/"
const plasmicData = await PLASMIC.maybeFetchComponentData(
plasmicPath,
"Header",
"Footer",
"Sidebar"
)
if (!plasmicData) return { props: {} }
const pageMeta = plasmicData.entryCompMetas[0]
// This is a path that Plasmic knows about.
// Cache the necessary data fetched for the page.
const queryCache = await extractPlasmicQueryData(
<HydrogenProvider>
<CartProvider>
<PlasmicRootProvider loader={PLASMIC} prefetchedData={plasmicData} pageParams={pageMeta.params}>
<PlasmicComponent
component={plasmicData.entryCompMetas[0].displayName}
/>
</PlasmicRootProvider>
</CartProvider>
</HydrogenProvider>
)
return {
props: { plasmicData, queryCache },
revalidate: 300,
}
}
/**
* Actually render the page!
*/
export default function CatchallPage(props: {
plasmicData?: ComponentRenderData
queryCache?: Record<string, any>
}) {
const { plasmicData } = props
if (!plasmicData || plasmicData.entryCompMetas.length === 0) {
return <Error statusCode={404} />
}
const pageMeta = plasmicData.entryCompMetas[0]
return <PlasmicComponent component={pageMeta.displayName} />
}
import "../style.scss"
import type { AppProps } from "next/app"
import Head from "next/head"
import Script from "next/script"
import { useRouter } from "next/router"
import { CartProvider } from "@shopify/hydrogen"
import { PlasmicRootProvider } from "@plasmicapp/loader-nextjs"
import Layout from "~/Layout"
import Hydrogen from "~/Hydrogen"
import { PLASMIC } from "plasmic.client"
function MyApp({ Component, pageProps }: AppProps) {
const router = useRouter()
const inEditor = (Component as any).isPlasmicHost
return (
<Hydrogen.Provider>
<CartProvider>
<PlasmicRootProvider
loader={PLASMIC}
prefetchedData={pageProps.plasmicData}
prefetchedQueryData={pageProps.queryCache}
skipFonts={true}
pageQuery={router.query}
pageParams={pageProps.plasmicData?.entryCompMetas[0].params}
>
<Head>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0,user-scalable=0"
/>
</Head>
<Layout render={!inEditor}>
<Component {...pageProps} />
</Layout>
</PlasmicRootProvider>
</CartProvider>
</Hydrogen.Provider>
)
}
export default MyApp
import dynamic from "next/dynamic"
import { useRouter } from "next/router"
import { AnimatePresence, motion } from "framer-motion"
import { PlasmicComponent } from "@plasmicapp/loader-nextjs"
import useSettings from "hooks/useSettings"
import CartButton from "~/Cart/Button"
import NavigationOverlay from "~/NavigationOverlay"
import React from "react"
const CartModal = dynamic(() => import("~/Cart/Modal"), { ssr: false })
interface LayoutProps {
children: React.ReactNode
render: boolean
}
const Layout = ({ children, render }: LayoutProps) => {
if (!render) return <>{children}</>
console.log("layout") // Runs twice
return (
<>
<div className="container">
<PlasmicComponent component="Header" />
<div className="flex gap-8 relative md:min-h-[90vh]">
<PlasmicComponent component="Sidebar" />
<main>{children}</main>
</div>
</div>
<PlasmicComponent component="Footer" />
<CartModal />
</>
)
}
export default Layout
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment