Skip to content
Open
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
10 changes: 8 additions & 2 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
{
"extends": "next/core-web-vitals"
}
"extends": "next/core-web-vitals",
"rules": {
"@next/next/no-html-link-for-pages": [
"warn",
"app/"
]
}
}
10 changes: 0 additions & 10 deletions app/403/page.tsx

This file was deleted.

82 changes: 50 additions & 32 deletions app/[...slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,29 @@
import { getPageTemplate } from "components/agility-layouts"
import { PageProps, getAgilityPage } from "lib/cms/getAgilityPage"
import { getAgilityContext } from "lib/cms/useAgilityContext"
import { getAgilityPage } from "lib/cms/getAgilityPage"

import { Metadata, ResolvingMetadata } from "next"

import { resolveAgilityMetaData } from "lib/cms-content/resolveAgilityMetaData"
import { notFound } from "next/navigation"
import { notFound, redirect } from "next/navigation"
import InlineError from "components/common/InlineError"
import { cacheConfig } from "lib/cms/cacheConfig"
import { DateTime } from "luxon"

import agilitySDK from "@agility/content-fetch"
import { SitemapNode } from "lib/types/SitemapNode"
import { getRichSnippet } from "lib/cms-content/getRichSnippet"
import { getAgilityContext } from "lib/cms/getAgilityContext"
import Link from 'next/link'

export const revalidate = cacheConfig.pathRevalidateDuration
export const revalidate = 60 //cacheConfig.pathRevalidateDuration
export const dynamicParams = true

interface NestedSitemapNode {
title: string
name: string
pageID: number
menuText: string
visible: {
menu: boolean
sitemap: boolean
}
path: string
redirect: string | null
isFolder: boolean
contentID?: number
children?: NestedSitemapNode[]
}

/**
* Generate the list of pages that we want to generate a build time
* @returns
*/
export async function generateStaticParams() {


console.log("*** generateStaticParams ***")
const isDevelopmentMode = process.env.NODE_ENV === "development"
const isPreview = isDevelopmentMode
Expand Down Expand Up @@ -88,24 +72,58 @@ export async function generateStaticParams() {
return paths
}

type MetaDataProps = {
params: Promise<{ slug: string[] }>
searchParams: Promise<{ [key: string]: string | string[] | undefined }>
}

/**
* Generate metadata for this page
*/
export async function generateMetadata(
{ params, searchParams }: PageProps,
{ params, searchParams }: MetaDataProps,
parent: ResolvingMetadata
): Promise<Metadata> {

const actualParams = await params;
// read route params
const { locale, sitemap, isDevelopmentMode, isPreview } = getAgilityContext()
const { locale, sitemap, isDevelopmentMode, isPreview } = await getAgilityContext()

const agilityData = await getAgilityPage({ params })
const agilityData = await getAgilityPage({ params: actualParams })

if (!agilityData.page) return {}
return await resolveAgilityMetaData({ agilityData, locale, sitemap, isDevelopmentMode, isPreview, parent })
}

export default async function Page({ params }: PageProps) {
const agilityData = await getAgilityPage({ params })
export default async function Page({
params,
searchParams,
}: {
params: Promise<{ slug: string[] }>
searchParams: Promise<{ [key: string]: string | string[] | undefined }>
}) {


const actualParams = await params

const agilityData = await getAgilityPage({
params: actualParams
})



if (agilityData?.sitemapNode?.redirect?.url) {
//handle redirects from the sitemap
let redirectUrl = agilityData.sitemapNode.redirect.url || ""
if (redirectUrl) {
//remove the ~/ from the redirect URL
if (redirectUrl.startsWith("~/")) {
redirectUrl = redirectUrl.substring(1)
}

redirect(redirectUrl)
}
}

//if the page is not found...
if (!agilityData.page) {
Expand All @@ -118,20 +136,20 @@ export default async function Page({ params }: PageProps) {
const jsonLD = getRichSnippet(agilityData)

return (
<div
(<div
data-agility-page={agilityData.page?.pageID}
data-agility-dynamic-content={agilityData.sitemapNode.contentID}
>
{jsonLD && (
//include the rich snipped if we have one
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: jsonLD }} />
(<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: jsonLD }} />)
)}
{AgilityPageTemplate && <AgilityPageTemplate {...agilityData} />}
{!AgilityPageTemplate && (
// if we don't have a template for this page, show an error
<InlineError message={`No template found for page template name: ${agilityData.pageTemplateName}`} />
(<InlineError message={`No template found for page template name: ${agilityData.pageTemplateName}`} />)
)}
<div className="hidden">Rendered on: {renderTimeStr}</div>
</div>
)
<div className="hidden">Rendered on: {renderTimeStr} <Link href="/">Go Home</Link></div>
</div>)
);
}
8 changes: 3 additions & 5 deletions app/api/dynamic-redirect/route.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { getDynamicPageURL } from "@agility/nextjs/node";
import { revalidatePath, revalidateTag } from "next/cache";
import { NextRequest, NextResponse } from "next/server";
import { NextRequest } from "next/server";
import { draftMode } from "next/headers"
import { url } from "inspector";

export async function GET(req: NextRequest, res: NextResponse) {
export async function GET(req: NextRequest) {

const searchParams = req.nextUrl.searchParams
const contentIDStr = searchParams.get("ContentID") as string

const contentID = parseInt(contentIDStr)

const preview = draftMode().isEnabled
const preview = (await draftMode()).isEnabled

if (!isNaN(contentID) && contentID > 0) {
//*** this is a dynamic page request ***
Expand Down
8 changes: 4 additions & 4 deletions app/api/preview/exit/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import { getDynamicPageURL } from '@agility/nextjs/node';
import { draftMode } from 'next/headers'
import { NextRequest, NextResponse } from "next/server";

export async function GET(request: NextRequest, res: NextResponse) {
export async function GET(request: NextRequest) {

const searchParams = request.nextUrl.searchParams

const slug = searchParams.get('slug')
const ContentID = searchParams.get('ContentID')
const slug = searchParams.get('slug');
const ContentID = searchParams.get('ContentID');

//disable draft/preview mode
draftMode().disable()
(await draftMode()).disable();

let url = `${slug}`

Expand Down
4 changes: 2 additions & 2 deletions app/api/preview/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { NextRequest, NextResponse } from "next/server";
* @param res
* @returns
*/
export async function GET(request: NextRequest, res: NextResponse) {
export async function GET(request: NextRequest) {

const searchParams = request.nextUrl.searchParams

Expand Down Expand Up @@ -46,7 +46,7 @@ export async function GET(request: NextRequest, res: NextResponse) {
}

//enable draft/preview mode
draftMode().enable()
(await draftMode()).enable()

// Redirect to the slug
//Add an extra querystring to the location header - since Netlify will keep the QS for the incoming request by default
Expand Down
2 changes: 1 addition & 1 deletion app/api/revalidate/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ interface IRevalidateRequest {
changeDateUTC?: string
}

export async function POST(req: NextRequest, res: NextResponse) {
export async function POST(req: NextRequest) {

//parse the body
const data = await req.json() as IRevalidateRequest
Expand Down
20 changes: 12 additions & 8 deletions app/[...slug]/error.tsx → app/error.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
"use client"
'use client' // Error boundaries must be Client Components

// 'use client' marks this page as a Client Component
// https://beta.nextjs.org/docs/rendering/server-and-client-components
import { useEffect } from 'react'

import {useEffect} from "react"

export default function Error({error, reset}: {error: Error; reset: () => void}) {
export default function Error({
error,
reset,
}: {
error: Error & { digest?: string }
reset: () => void
}) {
useEffect(() => {
// Log the error to an error reporting service
console.error(error)
console.error("An error occurred:", error)
}, [error])


let message = `An unexpected error has occurred.`
let title = `Error`
if (error.message === "404") {
Expand All @@ -26,4 +30,4 @@ export default function Error({error, reset}: {error: Error; reset: () => void})
</div>
</section>
)
}
}
11 changes: 11 additions & 0 deletions app/forbidden.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Link from 'next/link'

export default function Forbidden() {
return (
<div>
<h2>Forbidden</h2>
<p>You are not authorized to access this resource.</p>
<Link href="/">Return Home</Link>
</div>
)
}
32 changes: 16 additions & 16 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,35 @@ import PreviewBar from "components/common/PreviewBar"
import SiteFooter from "components/common/footer/SiteFooter"
import SiteHeader from "components/common/header/SiteHeader"

import { useAgilityContext } from "lib/cms/useAgilityContext"
import { GoogleTagManager } from "@next/third-parties/google"
import { getAgilityContext } from "lib/cms/getAgilityContext"

import "/styles/output.css"

import "../globals.css"

import { getHeaderContent } from "lib/cms-content/getHeaderContent"
import { redirect } from "next/navigation"
import Script from "next/script"
import HubspotTracker from "components/common/HubspotTracker"
import { Mulish } from 'next/font/google'
import { GoogleTagManager } from "components/common/GoogleTagManager"

// If loading a variable font, you don't need to specify the font weight
const mulish = Mulish({
subsets: ['latin'],
display: 'swap', //using swap to avoid render blocking
display: 'fallback', //using swap to avoid render blocking
variable: '--font-mulish',
})

export default async function RootLayout({ children }: { children: React.ReactNode }) {
const { locale, sitemap, isDevelopmentMode, isPreview } = useAgilityContext()
const { locale, sitemap, isDevelopmentMode, isPreview } = await getAgilityContext()

const headerContent = await getHeaderContent({ sitemap, locale })

async function startPreviewMode(pathname: string) {
"use server"
const startPreviewMode = async (pathname: string) => {
"use server";

//turn on draft/preview mode
draftMode().enable()
(await draftMode()).enable()

// Redirect to the same page
let url = `${pathname}`
Expand All @@ -45,17 +46,17 @@ export default async function RootLayout({ children }: { children: React.ReactNo
return (
<html lang="en" className={`font-sans text-primary ${mulish.variable}`}>
<head>
<head>
<link rel="preconnect" href="https://static.agilitycms.com" />

<link rel="preconnect" href="https://static.agilitycms.com" />


<link rel="preconnect" href="https://js.hsforms.net" />
<link rel="preconnect" href="https://forms.hsforms.com" />
<link rel="preconnect" href="https://www.googletagmanager.com" />
<link rel="preconnect" href="https://js.hsforms.net" />
<link rel="preconnect" href="https://forms.hsforms.com" />
<link rel="preconnect" href="https://www.googletagmanager.com" />


</head>
</head>

{process.env.GTM_ID && <GoogleTagManager gtmId={process.env.GTM_ID} />}
<body data-agility-guid={process.env.AGILITY_GUID}>
<div id="site-wrapper">
Expand All @@ -64,7 +65,6 @@ export default async function RootLayout({ children }: { children: React.ReactNo
<SiteHeader {...{ headerContent }} />

<main className={`flex-grow`}>

{children}</main>
<SiteFooter />
</div>
Expand All @@ -76,7 +76,7 @@ export default async function RootLayout({ children }: { children: React.ReactNo

<HubspotTracker />
{/* Load in the agility web-studio-sdk script */}
<Script src="https://unpkg.com/@agility/web-studio-sdk@latest/dist/index.js" />
<Script src="https://unpkg.com/@agility/web-studio-sdk@latest/dist/index.js" strategy="afterInteractive" />
</body>
</html>
)
Expand Down
4 changes: 4 additions & 0 deletions app/[...slug]/not-found.tsx → app/not-found.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import Link from 'next/link'
export default function NotFound() {
return (
<section className="relative px-8 ">
<div className="max-w-2xl mx-auto my-12 md:mt-18 lg:mt-20 prose prose-sm sm:prose lg:prose-lg xl:prose-xl">
<h1>Page Not Found</h1>
<p>The page you were looking for could not be found</p>
<div>
<Link href="/">Return Home</Link>
</div>
</div>
</section>
)
Expand Down
10 changes: 7 additions & 3 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ import { getSitemapFlat } from "lib/cms/getSitemapFlat"
/**
* the root page - just pull exports from the main slug...
*/
export { generateMetadata } from "./[...slug]/page"
export { default } from "./[...slug]/page"
export { /* @next-codemod-error `generateMetadata` export is re-exported. Check if this component uses `params` or `searchParams`*/
generateMetadata
} from "./[...slug]/page"
export { /* @next-codemod-error `default` export is re-exported. Check if this component uses `params` or `searchParams`*/
default
} from "./[...slug]/page"

export const revalidate = cacheConfig.pathRevalidateDuration
export const revalidate = 60; //cacheConfig.pathRevalidateDuration
export const dynamicParams = true
Loading