From 4af271909831fa3d611c558d3f892dd6197536a9 Mon Sep 17 00:00:00 2001 From: Matchu Date: Mon, 1 Nov 2021 23:03:19 -0700 Subject: [PATCH] [WIP] Use Next.js for outfit page SSR Hey cool, we can use this API now! I prefer this a lot to my (granted, very cool) HTML injection hacks lol --- pages/outfits/[id].js | 85 +++++++++++++++++++++++++++++++++++++++++++ pages/outfits/new.js | 19 ++++++++++ vercel.json | 2 - 3 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 pages/outfits/[id].js create mode 100644 pages/outfits/new.js diff --git a/pages/outfits/[id].js b/pages/outfits/[id].js new file mode 100644 index 0000000..82dbfa8 --- /dev/null +++ b/pages/outfits/[id].js @@ -0,0 +1,85 @@ +// This is a copy of our higher-level catch-all page, but with some +// extra SSR for outfit sharing meta tags! + +import Head from "next/head"; +import connectToDb from "../../src/server/db"; +import { normalizeRow } from "../../src/server/util"; + +// import NextIndexWrapper from '../../src' + +// next/dynamic is used to prevent breaking incompatibilities +// with SSR from window.SOME_VAR usage, if this is not used +// next/dynamic can be removed to take advantage of SSR/prerendering +import dynamic from "next/dynamic"; + +// try changing "ssr" to true below to test for incompatibilities, if +// no errors occur the above static import can be used instead and the +// below removed +const NextIndexWrapper = dynamic(() => import("../../src"), { ssr: false }); + +export default function Page({ outfit, ...props }) { + return ( + <> + + {outfit.name || "Untitled outfit"} | Dress to Impress + + + + + ); +} + +function OutfitMetaTags({ outfit }) { + const updatedAtTimestamp = Math.floor( + new Date(outfit.updatedAt).getTime() / 1000 + ); + const outfitUrl = + `https://impress-2020.openneo.net/outfits` + + `/${encodeURIComponent(outfit.id)}`; + const imageUrl = + `https://impress-outfit-images.openneo.net/outfits` + + `/${encodeURIComponent(outfit.id)}` + + `/v/${encodeURIComponent(updatedAtTimestamp)}` + + `/600.png`; + + return ( + <> + + + + + + + + ); +} + +export async function getServerSideProps({ params }) { + const outfit = await loadOutfitData(params.id); + if (outfit == null) { + return { notFound: true }; + } + + return { + props: { + outfit: { + id: outfit.id, + name: outfit.name, + updatedAt: outfit.updatedAt.toISOString(), + }, + }, + }; +} + +async function loadOutfitData(id) { + const db = await connectToDb(); + const [rows] = await db.query(`SELECT * FROM outfits WHERE id = ?;`, [id]); + if (rows.length === 0) { + return null; + } + + return normalizeRow(rows[0]); +} diff --git a/pages/outfits/new.js b/pages/outfits/new.js new file mode 100644 index 0000000..ca1c079 --- /dev/null +++ b/pages/outfits/new.js @@ -0,0 +1,19 @@ +// This is just a copy of our higher-level catch-all page. +// That way, /outfits/new renders as normal, but /outfits/:slug +// does the SSR thing! + +// import NextIndexWrapper from '../../src' + +// next/dynamic is used to prevent breaking incompatibilities +// with SSR from window.SOME_VAR usage, if this is not used +// next/dynamic can be removed to take advantage of SSR/prerendering +import dynamic from "next/dynamic"; + +// try changing "ssr" to true below to test for incompatibilities, if +// no errors occur the above static import can be used instead and the +// below removed +const NextIndexWrapper = dynamic(() => import("../../src"), { ssr: false }); + +export default function Page(props) { + return ; +} diff --git a/vercel.json b/vercel.json index 8f26f76..969803f 100644 --- a/vercel.json +++ b/vercel.json @@ -1,7 +1,5 @@ { "routes": [ - { "src": "/outfits/new(\\?|$)", "dest": "/index.html" }, - { "src": "/outfits/(?[^/]+)", "dest": "/api/outfitPageSSR.js?id=$id" }, { "handle": "filesystem" },