Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use static rendering #732

Merged
merged 1 commit into from
Feb 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { gql, previewParams } from "@comet/cms-site";
import { GQLLayoutQuery, GQLLayoutQueryVariables } from "@src/app/[domain]/[language]/[[...path]]/layout.generated";
import { gql } from "@comet/cms-site";
import { Footer } from "@src/layout/footer/Footer";
import { footerFragment } from "@src/layout/footer/Footer.fragment";
import { Header } from "@src/layout/header/Header";
Expand All @@ -9,13 +8,14 @@ import { getSiteConfigForDomain } from "@src/util/siteConfig";
import type { Metadata } from "next";
import { PropsWithChildren } from "react";

import { GQLLayoutQuery, GQLLayoutQueryVariables } from "./layout.generated";

interface LayoutProps {
params: { domain: string; language: string };
}

export default async function Layout({ children, params: { domain, language } }: PropsWithChildren<LayoutProps>) {
const { previewData } = (await previewParams()) || { previewData: undefined };
const graphqlFetch = createGraphQLFetch(previewData);
const graphqlFetch = createGraphQLFetch();

const { header, footer } = await graphqlFetch<GQLLayoutQuery, GQLLayoutQueryVariables>(
gql`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { gql, previewParams } from "@comet/cms-site";
export const dynamic = "error";

import { gql } from "@comet/cms-site";
import { ExternalLinkBlockData, InternalLinkBlockData, RedirectsLinkBlockData } from "@src/blocks.generated";
import { documentTypes } from "@src/documents";
import { GQLPageTreeNodeScope } from "@src/graphql.generated";
import { VisibilityParam } from "@src/middleware/domainRewrite";
import { createGraphQLFetch } from "@src/util/graphQLClient";
import { setVisibilityParam } from "@src/util/ServerContext";
import { getSiteConfigForDomain } from "@src/util/siteConfig";
import { Metadata, ResolvingMetadata } from "next";
import { notFound, redirect } from "next/navigation";
Expand All @@ -28,7 +32,6 @@ const documentTypeQuery = gql`
`;

async function fetchPageTreeNode(params: { path: string[]; domain: string; language: string }) {
const { previewData } = (await previewParams()) || { previewData: undefined };
const siteConfig = getSiteConfigForDomain(params.domain);

// Redirects are scoped by domain only, not by language.
Expand All @@ -38,7 +41,7 @@ async function fetchPageTreeNode(params: { path: string[]; domain: string; langu

const path = `/${(params.path ?? []).join("/")}`;
const { scope } = { scope: { domain: params.domain, language: params.language } };
const graphQLFetch = createGraphQLFetch(previewData);
const graphQLFetch = createGraphQLFetch();

return graphQLFetch<GQLDocumentTypeQuery, GQLDocumentTypeQueryVariables>(
documentTypeQuery,
Expand All @@ -54,10 +57,12 @@ async function fetchPageTreeNode(params: { path: string[]; domain: string; langu
}

interface PageProps {
params: { path: string[]; domain: string; language: string };
params: { path: string[]; domain: string; language: string; visibility: VisibilityParam };
}

export default async function Page({ params }: PageProps) {
setVisibilityParam(params.visibility);

const scope = { domain: params.domain, language: params.language };
const data = await fetchPageTreeNode(params);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { SitePreviewProvider } from "@comet/cms-site";
import { IntlProvider } from "@src/util/IntlProvider";
import { loadMessages } from "@src/util/loadMessages";
import { setNotFoundContext } from "@src/util/NotFoundContext";
import { setNotFoundContext } from "@src/util/ServerContext";
import { getSiteConfigForDomain } from "@src/util/siteConfig";
import { SiteConfigProvider } from "@src/util/SiteConfigProvider";
import { draftMode } from "next/headers";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import NotFoundContent from "@src/documents/NotFound";
import { IntlProvider } from "@src/util/IntlProvider";
import { loadMessages } from "@src/util/loadMessages";
import { getNotFoundContext } from "@src/util/NotFoundContext";
import { getNotFoundContext } from "@src/util/ServerContext";
import { getSiteConfigForDomain } from "@src/util/siteConfig";
import { SiteConfigProvider } from "@src/util/SiteConfigProvider";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@
import { BlockPreviewProvider, IFrameBridgeProvider, useBlockPreviewFetch, useIFrameBridge } from "@comet/cms-site";
import { FooterContentBlockData } from "@src/blocks.generated";
import { FooterContentBlock } from "@src/layout/footer/blocks/FooterContentBlock";
import { graphQLApiUrl } from "@src/util/graphQLClient";
import { recursivelyLoadBlockData } from "@src/util/recursivelyLoadBlockData";
import { FunctionComponent, useEffect, useState } from "react";

const PreviewPage: FunctionComponent = () => {
const iFrameBridge = useIFrameBridge();

const { fetch, graphQLFetch } = useBlockPreviewFetch(graphQLApiUrl);
const { fetch, graphQLFetch } = useBlockPreviewFetch();

const [blockData, setBlockData] = useState<FooterContentBlockData>();
useEffect(() => {
async function load() {
if (!graphQLFetch) return;
if (!iFrameBridge.block) {
setBlockData(undefined);
return;
Expand Down
4 changes: 2 additions & 2 deletions site/src/app/block-preview/[domain]/[language]/page/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ import { useBlockPreviewFetch, useIFrameBridge } from "@comet/cms-site";
import { PageContentBlockData } from "@src/blocks.generated";
import { PageContentBlock } from "@src/documents/pages/blocks/PageContentBlock";
import { withBlockPreview } from "@src/util/blockPreview";
import { graphQLApiUrl } from "@src/util/graphQLClient";
import { recursivelyLoadBlockData } from "@src/util/recursivelyLoadBlockData";
import { useEffect, useState } from "react";

export default withBlockPreview(() => {
const iFrameBridge = useIFrameBridge();

const { fetch, graphQLFetch } = useBlockPreviewFetch(graphQLApiUrl);
const { fetch, graphQLFetch } = useBlockPreviewFetch();

const [blockData, setBlockData] = useState<PageContentBlockData>();
useEffect(() => {
async function load() {
if (!graphQLFetch) return;
if (!iFrameBridge.block) {
setBlockData(undefined);
return;
Expand Down
5 changes: 2 additions & 3 deletions site/src/documents/links/Link.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { gql, previewParams } from "@comet/cms-site";
import { gql } from "@comet/cms-site";
import { ExternalLinkBlockData, InternalLinkBlockData } from "@src/blocks.generated";
import { GQLPageTreeNodeScopeInput } from "@src/graphql.generated";
import { createGraphQLFetch } from "@src/util/graphQLClient";
Expand All @@ -25,8 +25,7 @@ interface Props {
}

export async function Link({ pageTreeNodeId }: Props): Promise<JSX.Element> {
const { previewData } = (await previewParams()) || { previewData: undefined };
const graphqlFetch = createGraphQLFetch(previewData);
const graphqlFetch = createGraphQLFetch();

const { pageTreeNode } = await graphqlFetch<GQLLinkRedirectQuery, GQLLinkRedirectQueryVariables>(linkRedirectQuery, {
id: pageTreeNodeId,
Expand Down
10 changes: 4 additions & 6 deletions site/src/documents/pages/Page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { generateImageUrl, gql, previewParams } from "@comet/cms-site";
import { generateImageUrl, gql } from "@comet/cms-site";
import { GQLPageTreeNodeScopeInput } from "@src/graphql.generated";
import { createGraphQLFetch } from "@src/util/graphQLClient";
import { recursivelyLoadBlockData } from "@src/util/recursivelyLoadBlockData";
Expand Down Expand Up @@ -29,9 +29,8 @@ const pageQuery = gql`

type Props = { pageTreeNodeId: string; scope: GQLPageTreeNodeScopeInput };

async function fetchData({ pageTreeNodeId, scope }: Props) {
const { previewData } = (await previewParams()) || { previewData: undefined };
const graphQLFetch = createGraphQLFetch(previewData);
async function fetchData({ pageTreeNodeId }: Props) {
const graphQLFetch = createGraphQLFetch();

const props = await graphQLFetch<GQLPageQuery, GQLPageQueryVariables>(
pageQuery,
Expand Down Expand Up @@ -96,8 +95,7 @@ export async function generateMetadata({ pageTreeNodeId, scope }: Props, parent:
}

export async function Page({ pageTreeNodeId, scope }: { pageTreeNodeId: string; scope: GQLPageTreeNodeScopeInput }) {
const { previewData } = (await previewParams()) || { previewData: undefined };
const graphQLFetch = createGraphQLFetch(previewData);
const graphQLFetch = createGraphQLFetch();

const data = await fetchData({ pageTreeNodeId, scope });
const document = data?.pageContent?.document;
Expand Down
12 changes: 11 additions & 1 deletion site/src/middleware/domainRewrite.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { previewParams } from "@comet/cms-site";
import { getHostByHeaders, getSiteConfigForHost } from "@src/util/siteConfig";
import { NextRequest, NextResponse } from "next/server";

import { CustomMiddleware } from "./chain";

export type VisibilityParam = "default" | "invisiblePages" | "invisibleBlocks";

/**
* Rewrite request to include the matching domain (from http host) in the path, so the route can have [domain] as parameter.
*
Expand All @@ -16,9 +19,16 @@ export function withDomainRewriteMiddleware(middleware: CustomMiddleware) {
if (!siteConfig) {
throw new Error(`Cannot get siteConfig for host ${host}`);
}

const preview = await previewParams({ skipDraftModeCheck: true });
let visibilityParam: VisibilityParam = "default";
if (preview?.previewData) {
visibilityParam = preview.previewData.includeInvisible ? "invisibleBlocks" : "invisiblePages";
}

return NextResponse.rewrite(
new URL(
`/${siteConfig.scope.domain}${request.nextUrl.pathname}${
`/${visibilityParam}/${siteConfig.scope.domain}${request.nextUrl.pathname}${
request.nextUrl.searchParams.toString().length > 0 ? `?${request.nextUrl.searchParams.toString()}` : ""
}`,
request.url,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { VisibilityParam } from "@src/middleware/domainRewrite";
import type { ContentScope } from "@src/site-configs";
import { cache } from "react";

Expand All @@ -23,3 +24,4 @@ function createServerContext<T>(defaultValue: T): [() => T, (v: T) => void] {
}

export const [getNotFoundContext, setNotFoundContext] = createServerContext<ContentScope | null>(null);
export const [getVisibilityParam, setVisibilityParam] = createServerContext<VisibilityParam>("default");
35 changes: 24 additions & 11 deletions site/src/util/graphQLClient.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,38 @@
import {
convertPreviewDataToHeaders,
createFetchWithDefaults,
createFetchWithPreviewHeaders,
createGraphQLFetch as createGraphQLFetchLibrary,
SitePreviewData,
} from "@comet/cms-site";

const isServerSide = typeof window === "undefined";
export const graphQLApiUrl = `${isServerSide ? process.env.API_URL_INTERNAL : process.env.NEXT_PUBLIC_API_URL}/graphql`;
export function createGraphQLFetch(previewData?: SitePreviewData) {
const headers: HeadersInit = {
"x-relative-dam-urls": "1",
};
import { getVisibilityParam } from "./ServerContext";

if (isServerSide) {
headers.authorization = `Basic ${Buffer.from(`system-user:${process.env.API_BASIC_AUTH_SYSTEM_USER_PASSWORD}`).toString("base64")}`;
export function createGraphQLFetch() {
if (typeof window !== "undefined") {
throw new Error("createGraphQLFetch: cannot use on client side.");
}
if (process.env.NEXT_RUNTIME === "edge") {
throw new Error("createGraphQLFetch: cannot use in edge runtime, use createGraphQLFetchMiddleware instead.");
}

let previewData: SitePreviewData | undefined;
const visibilityParam = getVisibilityParam();
if (visibilityParam === "invisibleBlocks") previewData = { includeInvisible: true };
if (visibilityParam === "invisiblePages") previewData = { includeInvisible: false };

return createGraphQLFetchLibrary(
// set a default revalidate time of 7.5 minutes to get an effective cache duration of 15 minutes if a CDN cache is enabled
// see cache-handler.ts for maximum cache duration (24 hours)
createFetchWithDefaults(createFetchWithPreviewHeaders(fetch, previewData), { next: { revalidate: 7.5 * 60 }, headers }),
graphQLApiUrl,
createFetchWithDefaults(fetch, {
next: {
revalidate: 7.5 * 60,
},
headers: {
"x-relative-dam-urls": "1",
authorization: `Basic ${Buffer.from(`vivid:${process.env.API_PASSWORD}`).toString("base64")}`,
...convertPreviewDataToHeaders(previewData),
},
}),
`${process.env.API_URL_INTERNAL}/graphql`,
);
}