From 12330e84afe83d3c8f533a2997a44eceb6d84b06 Mon Sep 17 00:00:00 2001 From: Tom Lienard Date: Sun, 31 Dec 2023 11:54:55 +0100 Subject: [PATCH 1/3] fix: static shell --- apps/dashboard/src/app/layout.tsx | 19 ++++------------ apps/dashboard/src/app/my-images/page.tsx | 2 ++ apps/dashboard/src/app/page.tsx | 2 ++ apps/dashboard/src/app/templates/page.tsx | 2 ++ .../dashboard/src/components/Splash/index.tsx | 22 +++++++++++++++++-- apps/dashboard/src/stores/imagesStore.ts | 3 ++- apps/dashboard/src/stores/zoomStore.ts | 1 + 7 files changed, 33 insertions(+), 18 deletions(-) diff --git a/apps/dashboard/src/app/layout.tsx b/apps/dashboard/src/app/layout.tsx index e3dd65f..b4b1844 100644 --- a/apps/dashboard/src/app/layout.tsx +++ b/apps/dashboard/src/app/layout.tsx @@ -1,17 +1,10 @@ -import type { Metadata } from 'next' import { Inter } from 'next/font/google' import { Toaster } from 'sonner' -import { Suspense } from 'react' import { Splash } from '../components/Splash' import './globals.css' const inter = Inter({ subsets: ['latin'] }) -export const metadata: Metadata = { - title: 'Create Next App', - description: 'Generated by create next app', -} - export default function RootLayout({ children, }: { @@ -20,15 +13,11 @@ export default function RootLayout({ return ( - {/* OgSplash uses `useSearchParams()` so we need to wrap it in a Suspense to allow to statically render the page - https://nextjs.org/docs/app/building-your-application/rendering/server-components#dynamic-functions */} - - - {children} - - + + {children} + - + ) } diff --git a/apps/dashboard/src/app/my-images/page.tsx b/apps/dashboard/src/app/my-images/page.tsx index 135717b..07aabbe 100644 --- a/apps/dashboard/src/app/my-images/page.tsx +++ b/apps/dashboard/src/app/my-images/page.tsx @@ -5,6 +5,8 @@ export const metadata = { description: 'My Open Graph images.', } +export const dynamic = 'force-static' + export default function MyImages() { return } diff --git a/apps/dashboard/src/app/page.tsx b/apps/dashboard/src/app/page.tsx index 8c28379..404d6bd 100644 --- a/apps/dashboard/src/app/page.tsx +++ b/apps/dashboard/src/app/page.tsx @@ -5,6 +5,8 @@ export const metadata = { description: 'Figma-like OG (Open Graph) Image builder.', } +export const dynamic = 'force-static' + export default function Home() { return } diff --git a/apps/dashboard/src/app/templates/page.tsx b/apps/dashboard/src/app/templates/page.tsx index 5c5abf2..83146fc 100644 --- a/apps/dashboard/src/app/templates/page.tsx +++ b/apps/dashboard/src/app/templates/page.tsx @@ -5,6 +5,8 @@ export const metadata = { description: 'Pre-made Open Graph image templates.', } +export const dynamic = 'force-static' + export default function Templates() { return } diff --git a/apps/dashboard/src/components/Splash/index.tsx b/apps/dashboard/src/components/Splash/index.tsx index ae48e1c..00fe842 100644 --- a/apps/dashboard/src/components/Splash/index.tsx +++ b/apps/dashboard/src/components/Splash/index.tsx @@ -1,18 +1,27 @@ 'use client' -import type { ReactNode } from "react"; +import { Suspense, type ReactNode, useEffect } from "react"; import { useSearchParams } from "next/navigation"; import { OgEditor } from "../OgEditor"; import { CustomLink } from "../CustomLink"; import { GitHubIcon } from "../icons/GitHubIcon"; +import { useImagesStore } from "../../stores/imagesStore"; +import { useZoomStore } from "../../stores/zoomStore"; interface OgSplashProps { children: ReactNode } -export function Splash({ children }: OgSplashProps) { +function SplashInner({ children }: OgSplashProps) { const searchParams = useSearchParams() const image = searchParams.get('i') + useEffect(() => { + // eslint-disable-next-line @typescript-eslint/no-floating-promises -- we don't want to wait for this + useImagesStore.persist.rehydrate() + // eslint-disable-next-line @typescript-eslint/no-floating-promises -- we don't want to wait for this + useZoomStore.persist.rehydrate() + }, []) + return ( <> @@ -43,3 +52,12 @@ export function Splash({ children }: OgSplashProps) { ) } +export function Splash({ children }: OgSplashProps) { + return ( + // SplashInner uses `useSearchParams()` so we need to wrap it in a Suspense to allow to statically render the page + // https://nextjs.org/docs/app/building-your-application/rendering/server-components#dynamic-functions + + {children} + + ) +} diff --git a/apps/dashboard/src/stores/imagesStore.ts b/apps/dashboard/src/stores/imagesStore.ts index 9bb89e1..ac138d7 100644 --- a/apps/dashboard/src/stores/imagesStore.ts +++ b/apps/dashboard/src/stores/imagesStore.ts @@ -80,5 +80,6 @@ export const useImagesStore = create(persist(set => ({ } }), { name: 'images', - storage: createJSONStorage(() => localStorage) + storage: createJSONStorage(() => localStorage), + skipHydration: true, })) diff --git a/apps/dashboard/src/stores/zoomStore.ts b/apps/dashboard/src/stores/zoomStore.ts index 738dbb7..a805b86 100644 --- a/apps/dashboard/src/stores/zoomStore.ts +++ b/apps/dashboard/src/stores/zoomStore.ts @@ -26,4 +26,5 @@ export const useZoomStore = create(persist((set, get) => ({ }), { name: 'zoom', storage: createJSONStorage(() => localStorage), + skipHydration: true, })) From 816c7bc42dc83e5ed079edc871e46bc8a637806a Mon Sep 17 00:00:00 2001 From: Tom Lienard Date: Sun, 31 Dec 2023 13:45:07 +0100 Subject: [PATCH 2/3] refactor: switch to dynamic route segment instead of search param, but fully static --- apps/dashboard/src/app/(splash)/layout.tsx | 13 ++++ .../src/app/{ => (splash)}/my-images/page.tsx | 4 +- .../dashboard/src/app/{ => (splash)}/page.tsx | 4 +- .../src/app/{ => (splash)}/templates/page.tsx | 4 +- apps/dashboard/src/app/[image]/page.tsx | 18 ++++++ apps/dashboard/src/app/layout.tsx | 5 +- apps/dashboard/src/components/OgEditor.tsx | 5 ++ .../src/components/Splash/HomeSplash.tsx | 6 +- .../src/components/Splash/MyImagesSplash.tsx | 4 +- .../dashboard/src/components/Splash/index.tsx | 59 +++++++------------ 10 files changed, 68 insertions(+), 54 deletions(-) create mode 100644 apps/dashboard/src/app/(splash)/layout.tsx rename apps/dashboard/src/app/{ => (splash)}/my-images/page.tsx (59%) rename apps/dashboard/src/app/{ => (splash)}/page.tsx (61%) rename apps/dashboard/src/app/{ => (splash)}/templates/page.tsx (61%) create mode 100644 apps/dashboard/src/app/[image]/page.tsx diff --git a/apps/dashboard/src/app/(splash)/layout.tsx b/apps/dashboard/src/app/(splash)/layout.tsx new file mode 100644 index 0000000..536b426 --- /dev/null +++ b/apps/dashboard/src/app/(splash)/layout.tsx @@ -0,0 +1,13 @@ +import { Splash } from '../../components/Splash' + +export default function Layout({ + children, +}: { + children: React.ReactNode +}) { + return ( + + {children} + + ) +} diff --git a/apps/dashboard/src/app/my-images/page.tsx b/apps/dashboard/src/app/(splash)/my-images/page.tsx similarity index 59% rename from apps/dashboard/src/app/my-images/page.tsx rename to apps/dashboard/src/app/(splash)/my-images/page.tsx index 07aabbe..a13a035 100644 --- a/apps/dashboard/src/app/my-images/page.tsx +++ b/apps/dashboard/src/app/(splash)/my-images/page.tsx @@ -1,11 +1,11 @@ -import { MyImagesSplash } from "../../components/Splash/MyImagesSplash"; +import { MyImagesSplash } from "../../../components/Splash/MyImagesSplash"; export const metadata = { title: 'My images - OG Studio', description: 'My Open Graph images.', } -export const dynamic = 'force-static' +// export const dynamic = 'force-static' export default function MyImages() { return diff --git a/apps/dashboard/src/app/page.tsx b/apps/dashboard/src/app/(splash)/page.tsx similarity index 61% rename from apps/dashboard/src/app/page.tsx rename to apps/dashboard/src/app/(splash)/page.tsx index 404d6bd..82ca42a 100644 --- a/apps/dashboard/src/app/page.tsx +++ b/apps/dashboard/src/app/(splash)/page.tsx @@ -1,11 +1,11 @@ -import { HomeSplash } from "../components/Splash/HomeSplash"; +import { HomeSplash } from "../../components/Splash/HomeSplash"; export const metadata = { title: 'OG Studio', description: 'Figma-like OG (Open Graph) Image builder.', } -export const dynamic = 'force-static' +// export const dynamic = 'force-static' export default function Home() { return diff --git a/apps/dashboard/src/app/templates/page.tsx b/apps/dashboard/src/app/(splash)/templates/page.tsx similarity index 61% rename from apps/dashboard/src/app/templates/page.tsx rename to apps/dashboard/src/app/(splash)/templates/page.tsx index 83146fc..a01a0ec 100644 --- a/apps/dashboard/src/app/templates/page.tsx +++ b/apps/dashboard/src/app/(splash)/templates/page.tsx @@ -1,11 +1,11 @@ -import { TemplatesSplash } from "../../components/Splash/TemplatesSplash"; +import { TemplatesSplash } from "../../../components/Splash/TemplatesSplash"; export const metadata = { title: 'Templates - OG Studio', description: 'Pre-made Open Graph image templates.', } -export const dynamic = 'force-static' +// export const dynamic = 'force-static' export default function Templates() { return diff --git a/apps/dashboard/src/app/[image]/page.tsx b/apps/dashboard/src/app/[image]/page.tsx new file mode 100644 index 0000000..67f426b --- /dev/null +++ b/apps/dashboard/src/app/[image]/page.tsx @@ -0,0 +1,18 @@ +import { OgEditor } from "../../components/OgEditor"; + +export const metadata = { + title: 'OG Studio', + description: 'Figma-like OG (Open Graph) Image builder.', +} + +export const dynamic = 'force-static' + +interface ImageProps { + params: { + image: string + } +} + +export default function Image({ params: { image } }: ImageProps) { + return +} diff --git a/apps/dashboard/src/app/layout.tsx b/apps/dashboard/src/app/layout.tsx index b4b1844..6773bfa 100644 --- a/apps/dashboard/src/app/layout.tsx +++ b/apps/dashboard/src/app/layout.tsx @@ -1,6 +1,5 @@ import { Inter } from 'next/font/google' import { Toaster } from 'sonner' -import { Splash } from '../components/Splash' import './globals.css' const inter = Inter({ subsets: ['latin'] }) @@ -13,9 +12,7 @@ export default function RootLayout({ return ( - - {children} - + {children} diff --git a/apps/dashboard/src/components/OgEditor.tsx b/apps/dashboard/src/components/OgEditor.tsx index 7e03bc4..09c2345 100644 --- a/apps/dashboard/src/components/OgEditor.tsx +++ b/apps/dashboard/src/components/OgEditor.tsx @@ -40,6 +40,11 @@ export function OgEditor({ imageId, width, height }: OgProviderProps) { const { selectedElementId, setSelectedElementId, elements, updateElement, removeElement, addElement, loadImage } = useElementsStore() const { undo, redo } = useElementsStore.temporal.getState() + useEffect(() => { + // eslint-disable-next-line @typescript-eslint/no-floating-promises -- we don't want to wait for this + useZoomStore.persist.rehydrate() + }, []) + /** * When the editor image is updated or loaded for the first time, reset every * state, and load the elements and fonts. diff --git a/apps/dashboard/src/components/Splash/HomeSplash.tsx b/apps/dashboard/src/components/Splash/HomeSplash.tsx index b3d4d79..fb11028 100644 --- a/apps/dashboard/src/components/Splash/HomeSplash.tsx +++ b/apps/dashboard/src/components/Splash/HomeSplash.tsx @@ -29,7 +29,7 @@ export function HomeSplash() { name={template.name} onClick={() => { const { id } = copyTemplate(template) - router.push(`/?i=${id}`) + router.push(`/${id}`) }} /> ))} @@ -46,7 +46,7 @@ export function HomeSplash() {
{ const { id } = createEmptyImage() - router.push(`/?i=${id}`) + router.push(`/${id}`) }}> Start from scratch @@ -55,7 +55,7 @@ export function HomeSplash() { copiable={() => copyImage(image)} deletable={() => { deleteImage(image); }} elements={JSON.parse(localStorage.getItem(image.id) || '[]') as OGElement[]} - href={`/?i=${image.id}`} + href={`/${image.id}`} key={image.id} name={image.name} /> diff --git a/apps/dashboard/src/components/Splash/MyImagesSplash.tsx b/apps/dashboard/src/components/Splash/MyImagesSplash.tsx index 942b34a..b0738cc 100644 --- a/apps/dashboard/src/components/Splash/MyImagesSplash.tsx +++ b/apps/dashboard/src/components/Splash/MyImagesSplash.tsx @@ -22,7 +22,7 @@ export function MyImagesSplash() {
{ const { id } = createEmptyImage() - router.push(`/?i=${id}`) + router.push(`/${id}`) }}> Start from scratch @@ -31,7 +31,7 @@ export function MyImagesSplash() { copiable={() => copyImage(image)} deletable={() => { deleteImage(image); }} elements={JSON.parse(localStorage.getItem(image.id) || '[]') as OGElement[]} - href={`/?i=${image.id}`} + href={`/${image.id}`} key={image.id} name={image.name} /> diff --git a/apps/dashboard/src/components/Splash/index.tsx b/apps/dashboard/src/components/Splash/index.tsx index 00fe842..c1b2e8c 100644 --- a/apps/dashboard/src/components/Splash/index.tsx +++ b/apps/dashboard/src/components/Splash/index.tsx @@ -1,63 +1,44 @@ 'use client' -import { Suspense, type ReactNode, useEffect } from "react"; -import { useSearchParams } from "next/navigation"; +import { type ReactNode, useEffect } from "react"; import { OgEditor } from "../OgEditor"; import { CustomLink } from "../CustomLink"; import { GitHubIcon } from "../icons/GitHubIcon"; import { useImagesStore } from "../../stores/imagesStore"; -import { useZoomStore } from "../../stores/zoomStore"; interface OgSplashProps { children: ReactNode } -function SplashInner({ children }: OgSplashProps) { - const searchParams = useSearchParams() - const image = searchParams.get('i') - +export function Splash({ children }: OgSplashProps) { useEffect(() => { // eslint-disable-next-line @typescript-eslint/no-floating-promises -- we don't want to wait for this useImagesStore.persist.rehydrate() - // eslint-disable-next-line @typescript-eslint/no-floating-promises -- we don't want to wait for this - useZoomStore.persist.rehydrate() }, []) return ( <> - - {image ? null : ( -
-
-
-
-

OG Studio

- - Early preview - - } target="_blank"> - GitHub - -
- } iconPosition="right"> - Guest + +
+
+
+
+

OG Studio

+ + Early preview + + } target="_blank"> + GitHub
-

Create static or dynamic Open Graph images with an intuitive, Figma-like visual editor. Browse ready-to-use templates, and export your images to SVG/PNG or to a dynamic URL.

-
- {children} + } iconPosition="right"> + Guest +
+

Create static or dynamic Open Graph images with an intuitive, Figma-like visual editor. Browse ready-to-use templates, and export your images to SVG/PNG or to a dynamic URL.

+
+ {children}
- )} +
) } - -export function Splash({ children }: OgSplashProps) { - return ( - // SplashInner uses `useSearchParams()` so we need to wrap it in a Suspense to allow to statically render the page - // https://nextjs.org/docs/app/building-your-application/rendering/server-components#dynamic-functions - - {children} - - ) -} From d9effd0b6874875e6dfc2d70d1f86fa2567d5088 Mon Sep 17 00:00:00 2001 From: Tom Lienard Date: Sun, 31 Dec 2023 13:52:04 +0100 Subject: [PATCH 3/3] Revert "refactor: switch to dynamic route segment instead of search param, but fully static" This reverts commit 816c7bc42dc83e5ed079edc871e46bc8a637806a. --- apps/dashboard/src/app/(splash)/layout.tsx | 13 ---- apps/dashboard/src/app/[image]/page.tsx | 18 ------ apps/dashboard/src/app/layout.tsx | 5 +- .../src/app/{(splash) => }/my-images/page.tsx | 4 +- .../dashboard/src/app/{(splash) => }/page.tsx | 4 +- .../src/app/{(splash) => }/templates/page.tsx | 4 +- apps/dashboard/src/components/OgEditor.tsx | 5 -- .../src/components/Splash/HomeSplash.tsx | 6 +- .../src/components/Splash/MyImagesSplash.tsx | 4 +- .../dashboard/src/components/Splash/index.tsx | 59 ++++++++++++------- 10 files changed, 54 insertions(+), 68 deletions(-) delete mode 100644 apps/dashboard/src/app/(splash)/layout.tsx delete mode 100644 apps/dashboard/src/app/[image]/page.tsx rename apps/dashboard/src/app/{(splash) => }/my-images/page.tsx (59%) rename apps/dashboard/src/app/{(splash) => }/page.tsx (61%) rename apps/dashboard/src/app/{(splash) => }/templates/page.tsx (61%) diff --git a/apps/dashboard/src/app/(splash)/layout.tsx b/apps/dashboard/src/app/(splash)/layout.tsx deleted file mode 100644 index 536b426..0000000 --- a/apps/dashboard/src/app/(splash)/layout.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { Splash } from '../../components/Splash' - -export default function Layout({ - children, -}: { - children: React.ReactNode -}) { - return ( - - {children} - - ) -} diff --git a/apps/dashboard/src/app/[image]/page.tsx b/apps/dashboard/src/app/[image]/page.tsx deleted file mode 100644 index 67f426b..0000000 --- a/apps/dashboard/src/app/[image]/page.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { OgEditor } from "../../components/OgEditor"; - -export const metadata = { - title: 'OG Studio', - description: 'Figma-like OG (Open Graph) Image builder.', -} - -export const dynamic = 'force-static' - -interface ImageProps { - params: { - image: string - } -} - -export default function Image({ params: { image } }: ImageProps) { - return -} diff --git a/apps/dashboard/src/app/layout.tsx b/apps/dashboard/src/app/layout.tsx index 6773bfa..b4b1844 100644 --- a/apps/dashboard/src/app/layout.tsx +++ b/apps/dashboard/src/app/layout.tsx @@ -1,5 +1,6 @@ import { Inter } from 'next/font/google' import { Toaster } from 'sonner' +import { Splash } from '../components/Splash' import './globals.css' const inter = Inter({ subsets: ['latin'] }) @@ -12,7 +13,9 @@ export default function RootLayout({ return ( - {children} + + {children} + diff --git a/apps/dashboard/src/app/(splash)/my-images/page.tsx b/apps/dashboard/src/app/my-images/page.tsx similarity index 59% rename from apps/dashboard/src/app/(splash)/my-images/page.tsx rename to apps/dashboard/src/app/my-images/page.tsx index a13a035..07aabbe 100644 --- a/apps/dashboard/src/app/(splash)/my-images/page.tsx +++ b/apps/dashboard/src/app/my-images/page.tsx @@ -1,11 +1,11 @@ -import { MyImagesSplash } from "../../../components/Splash/MyImagesSplash"; +import { MyImagesSplash } from "../../components/Splash/MyImagesSplash"; export const metadata = { title: 'My images - OG Studio', description: 'My Open Graph images.', } -// export const dynamic = 'force-static' +export const dynamic = 'force-static' export default function MyImages() { return diff --git a/apps/dashboard/src/app/(splash)/page.tsx b/apps/dashboard/src/app/page.tsx similarity index 61% rename from apps/dashboard/src/app/(splash)/page.tsx rename to apps/dashboard/src/app/page.tsx index 82ca42a..404d6bd 100644 --- a/apps/dashboard/src/app/(splash)/page.tsx +++ b/apps/dashboard/src/app/page.tsx @@ -1,11 +1,11 @@ -import { HomeSplash } from "../../components/Splash/HomeSplash"; +import { HomeSplash } from "../components/Splash/HomeSplash"; export const metadata = { title: 'OG Studio', description: 'Figma-like OG (Open Graph) Image builder.', } -// export const dynamic = 'force-static' +export const dynamic = 'force-static' export default function Home() { return diff --git a/apps/dashboard/src/app/(splash)/templates/page.tsx b/apps/dashboard/src/app/templates/page.tsx similarity index 61% rename from apps/dashboard/src/app/(splash)/templates/page.tsx rename to apps/dashboard/src/app/templates/page.tsx index a01a0ec..83146fc 100644 --- a/apps/dashboard/src/app/(splash)/templates/page.tsx +++ b/apps/dashboard/src/app/templates/page.tsx @@ -1,11 +1,11 @@ -import { TemplatesSplash } from "../../../components/Splash/TemplatesSplash"; +import { TemplatesSplash } from "../../components/Splash/TemplatesSplash"; export const metadata = { title: 'Templates - OG Studio', description: 'Pre-made Open Graph image templates.', } -// export const dynamic = 'force-static' +export const dynamic = 'force-static' export default function Templates() { return diff --git a/apps/dashboard/src/components/OgEditor.tsx b/apps/dashboard/src/components/OgEditor.tsx index 09c2345..7e03bc4 100644 --- a/apps/dashboard/src/components/OgEditor.tsx +++ b/apps/dashboard/src/components/OgEditor.tsx @@ -40,11 +40,6 @@ export function OgEditor({ imageId, width, height }: OgProviderProps) { const { selectedElementId, setSelectedElementId, elements, updateElement, removeElement, addElement, loadImage } = useElementsStore() const { undo, redo } = useElementsStore.temporal.getState() - useEffect(() => { - // eslint-disable-next-line @typescript-eslint/no-floating-promises -- we don't want to wait for this - useZoomStore.persist.rehydrate() - }, []) - /** * When the editor image is updated or loaded for the first time, reset every * state, and load the elements and fonts. diff --git a/apps/dashboard/src/components/Splash/HomeSplash.tsx b/apps/dashboard/src/components/Splash/HomeSplash.tsx index fb11028..b3d4d79 100644 --- a/apps/dashboard/src/components/Splash/HomeSplash.tsx +++ b/apps/dashboard/src/components/Splash/HomeSplash.tsx @@ -29,7 +29,7 @@ export function HomeSplash() { name={template.name} onClick={() => { const { id } = copyTemplate(template) - router.push(`/${id}`) + router.push(`/?i=${id}`) }} /> ))} @@ -46,7 +46,7 @@ export function HomeSplash() {
{ const { id } = createEmptyImage() - router.push(`/${id}`) + router.push(`/?i=${id}`) }}> Start from scratch @@ -55,7 +55,7 @@ export function HomeSplash() { copiable={() => copyImage(image)} deletable={() => { deleteImage(image); }} elements={JSON.parse(localStorage.getItem(image.id) || '[]') as OGElement[]} - href={`/${image.id}`} + href={`/?i=${image.id}`} key={image.id} name={image.name} /> diff --git a/apps/dashboard/src/components/Splash/MyImagesSplash.tsx b/apps/dashboard/src/components/Splash/MyImagesSplash.tsx index b0738cc..942b34a 100644 --- a/apps/dashboard/src/components/Splash/MyImagesSplash.tsx +++ b/apps/dashboard/src/components/Splash/MyImagesSplash.tsx @@ -22,7 +22,7 @@ export function MyImagesSplash() {
{ const { id } = createEmptyImage() - router.push(`/${id}`) + router.push(`/?i=${id}`) }}> Start from scratch @@ -31,7 +31,7 @@ export function MyImagesSplash() { copiable={() => copyImage(image)} deletable={() => { deleteImage(image); }} elements={JSON.parse(localStorage.getItem(image.id) || '[]') as OGElement[]} - href={`/${image.id}`} + href={`/?i=${image.id}`} key={image.id} name={image.name} /> diff --git a/apps/dashboard/src/components/Splash/index.tsx b/apps/dashboard/src/components/Splash/index.tsx index c1b2e8c..00fe842 100644 --- a/apps/dashboard/src/components/Splash/index.tsx +++ b/apps/dashboard/src/components/Splash/index.tsx @@ -1,44 +1,63 @@ 'use client' -import { type ReactNode, useEffect } from "react"; +import { Suspense, type ReactNode, useEffect } from "react"; +import { useSearchParams } from "next/navigation"; import { OgEditor } from "../OgEditor"; import { CustomLink } from "../CustomLink"; import { GitHubIcon } from "../icons/GitHubIcon"; import { useImagesStore } from "../../stores/imagesStore"; +import { useZoomStore } from "../../stores/zoomStore"; interface OgSplashProps { children: ReactNode } -export function Splash({ children }: OgSplashProps) { +function SplashInner({ children }: OgSplashProps) { + const searchParams = useSearchParams() + const image = searchParams.get('i') + useEffect(() => { // eslint-disable-next-line @typescript-eslint/no-floating-promises -- we don't want to wait for this useImagesStore.persist.rehydrate() + // eslint-disable-next-line @typescript-eslint/no-floating-promises -- we don't want to wait for this + useZoomStore.persist.rehydrate() }, []) return ( <> - -
-
-
-
-

OG Studio

- - Early preview - - } target="_blank"> - GitHub + + {image ? null : ( +
+
+
+
+

OG Studio

+ + Early preview + + } target="_blank"> + GitHub + +
+ } iconPosition="right"> + Guest
- } iconPosition="right"> - Guest - +

Create static or dynamic Open Graph images with an intuitive, Figma-like visual editor. Browse ready-to-use templates, and export your images to SVG/PNG or to a dynamic URL.

+
+ {children}
-

Create static or dynamic Open Graph images with an intuitive, Figma-like visual editor. Browse ready-to-use templates, and export your images to SVG/PNG or to a dynamic URL.

-
- {children}
-
+ )} ) } + +export function Splash({ children }: OgSplashProps) { + return ( + // SplashInner uses `useSearchParams()` so we need to wrap it in a Suspense to allow to statically render the page + // https://nextjs.org/docs/app/building-your-application/rendering/server-components#dynamic-functions + + {children} + + ) +}