prevent i18n flickering on pages (#1308)
* prevent i18n flickering on pages - 404 - `/cancel` - `/success` * ssg for 404 * comments * tweak * 404 Co-authored-by: Peer Richelsen <peeroke@gmail.com>
This commit is contained in:
parent
8e447ea4b5
commit
ad8ffd3de4
6 changed files with 71 additions and 1 deletions
|
@ -1,5 +1,6 @@
|
||||||
import { BookOpenIcon, CheckIcon, CodeIcon, DocumentTextIcon } from "@heroicons/react/outline";
|
import { BookOpenIcon, CheckIcon, CodeIcon, DocumentTextIcon } from "@heroicons/react/outline";
|
||||||
import { ChevronRightIcon } from "@heroicons/react/solid";
|
import { ChevronRightIcon } from "@heroicons/react/solid";
|
||||||
|
import { GetStaticPropsContext } from "next";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
@ -8,6 +9,8 @@ import { useLocale } from "@lib/hooks/useLocale";
|
||||||
|
|
||||||
import { HeadSeo } from "@components/seo/head-seo";
|
import { HeadSeo } from "@components/seo/head-seo";
|
||||||
|
|
||||||
|
import { ssgInit } from "@server/lib/ssg";
|
||||||
|
|
||||||
export default function Custom404() {
|
export default function Custom404() {
|
||||||
const { t } = useLocale();
|
const { t } = useLocale();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -170,3 +173,13 @@ export default function Custom404() {
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getStaticProps = async (context: GetStaticPropsContext) => {
|
||||||
|
const ssr = await ssgInit(context);
|
||||||
|
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
trpcState: ssr.dehydrate(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
|
@ -15,6 +15,8 @@ import CustomBranding from "@components/CustomBranding";
|
||||||
import { HeadSeo } from "@components/seo/head-seo";
|
import { HeadSeo } from "@components/seo/head-seo";
|
||||||
import { Button } from "@components/ui/Button";
|
import { Button } from "@components/ui/Button";
|
||||||
|
|
||||||
|
import { ssrInit } from "@server/lib/ssr";
|
||||||
|
|
||||||
export default function Type(props: inferSSRProps<typeof getServerSideProps>) {
|
export default function Type(props: inferSSRProps<typeof getServerSideProps>) {
|
||||||
const { t } = useLocale();
|
const { t } = useLocale();
|
||||||
// Get router variables
|
// Get router variables
|
||||||
|
@ -145,6 +147,7 @@ export default function Type(props: inferSSRProps<typeof getServerSideProps>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getServerSideProps = async (context: GetServerSidePropsContext) => {
|
export const getServerSideProps = async (context: GetServerSidePropsContext) => {
|
||||||
|
const ssr = await ssrInit(context);
|
||||||
const session = await getSession(context);
|
const session = await getSession(context);
|
||||||
const booking = await prisma.booking.findUnique({
|
const booking = await prisma.booking.findUnique({
|
||||||
where: {
|
where: {
|
||||||
|
@ -202,6 +205,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
|
||||||
booking: bookingObj,
|
booking: bookingObj,
|
||||||
cancellationAllowed:
|
cancellationAllowed:
|
||||||
(!!session?.user && session.user?.id === booking.user?.id) || booking.startTime >= new Date(),
|
(!!session?.user && session.user?.id === booking.user?.id) || booking.startTime >= new Date(),
|
||||||
|
trpcState: ssr.dehydrate(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,6 +22,8 @@ import CustomBranding from "@components/CustomBranding";
|
||||||
import { HeadSeo } from "@components/seo/head-seo";
|
import { HeadSeo } from "@components/seo/head-seo";
|
||||||
import Button from "@components/ui/Button";
|
import Button from "@components/ui/Button";
|
||||||
|
|
||||||
|
import { ssrInit } from "@server/lib/ssr";
|
||||||
|
|
||||||
dayjs.extend(utc);
|
dayjs.extend(utc);
|
||||||
dayjs.extend(toArray);
|
dayjs.extend(toArray);
|
||||||
dayjs.extend(timezone);
|
dayjs.extend(timezone);
|
||||||
|
@ -279,6 +281,7 @@ export default function Success(props: inferSSRProps<typeof getServerSideProps>)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getServerSideProps(context: GetServerSidePropsContext) {
|
export async function getServerSideProps(context: GetServerSidePropsContext) {
|
||||||
|
const ssr = await ssrInit(context);
|
||||||
const typeId = parseInt(asStringOrNull(context.query.type) ?? "");
|
const typeId = parseInt(asStringOrNull(context.query.type) ?? "");
|
||||||
|
|
||||||
if (isNaN(typeId)) {
|
if (isNaN(typeId)) {
|
||||||
|
@ -358,6 +361,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
||||||
hideBranding: eventType.team ? eventType.team.hideBranding : isBrandingHidden(eventType.users[0]),
|
hideBranding: eventType.team ? eventType.team.hideBranding : isBrandingHidden(eventType.users[0]),
|
||||||
profile,
|
profile,
|
||||||
eventType,
|
eventType,
|
||||||
|
trpcState: ssr.dehydrate(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
43
server/lib/ssg.ts
Normal file
43
server/lib/ssg.ts
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import { GetStaticPropsContext } from "next";
|
||||||
|
import { i18n } from "next-i18next.config";
|
||||||
|
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
|
||||||
|
import superjson from "superjson";
|
||||||
|
|
||||||
|
import prisma from "@lib/prisma";
|
||||||
|
|
||||||
|
import { appRouter } from "@server/routers/_app";
|
||||||
|
import { createSSGHelpers } from "@trpc/react/ssg";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize static site rendering tRPC helpers.
|
||||||
|
* Provides a method to prefetch tRPC-queries in a `getStaticProps`-function.
|
||||||
|
* Automatically prefetches i18n based on the passed in `context`-object to prevent i18n-flickering.
|
||||||
|
* Make sure to `return { props: { trpcState: ssr.dehydrate() } }` at the end.
|
||||||
|
*/
|
||||||
|
export async function ssgInit<TParams extends { locale?: string }>(opts: GetStaticPropsContext<TParams>) {
|
||||||
|
const requestedLocale = opts.params?.locale || opts.locale || i18n.defaultLocale;
|
||||||
|
const isSupportedLocale = i18n.locales.includes(requestedLocale);
|
||||||
|
if (!isSupportedLocale) {
|
||||||
|
console.warn(`Requested unsupported locale "${requestedLocale}"`);
|
||||||
|
}
|
||||||
|
const locale = isSupportedLocale ? requestedLocale : i18n.defaultLocale;
|
||||||
|
|
||||||
|
const _i18n = await serverSideTranslations(locale, ["common"]);
|
||||||
|
|
||||||
|
const ssg = createSSGHelpers({
|
||||||
|
router: appRouter,
|
||||||
|
transformer: superjson,
|
||||||
|
ctx: {
|
||||||
|
prisma,
|
||||||
|
session: null,
|
||||||
|
user: null,
|
||||||
|
locale,
|
||||||
|
i18n: _i18n,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// always preload i18n
|
||||||
|
await ssg.fetchQuery("viewer.i18n");
|
||||||
|
|
||||||
|
return ssg;
|
||||||
|
}
|
|
@ -6,6 +6,12 @@ import { createSSGHelpers } from "@trpc/react/ssg";
|
||||||
|
|
||||||
import { appRouter } from "../routers/_app";
|
import { appRouter } from "../routers/_app";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize server-side rendering tRPC helpers.
|
||||||
|
* Provides a method to prefetch tRPC-queries in a `getServerSideProps`-function.
|
||||||
|
* Automatically prefetches i18n based on the passed in `context`-object to prevent i18n-flickering.
|
||||||
|
* Make sure to `return { props: { trpcState: ssr.dehydrate() } }` at the end.
|
||||||
|
*/
|
||||||
export async function ssrInit(context: GetServerSidePropsContext) {
|
export async function ssrInit(context: GetServerSidePropsContext) {
|
||||||
const ctx = await createContext(context);
|
const ctx = await createContext(context);
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
"jest-playwright-preset",
|
"jest-playwright-preset",
|
||||||
"expect-playwright"
|
"expect-playwright"
|
||||||
],
|
],
|
||||||
"allowJs": false,
|
"allowJs": true,
|
||||||
"incremental": true
|
"incremental": true
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
|
|
Loading…
Reference in a new issue