;
+ };
+ query: {
+ uri: string;
+ publishingLevel: "PRODUCTION" | "REALTIME" | undefined;
+ pccGrant: string;
+ };
}) {
const slugOrId = uri[uri.length - 1];
const grant = pccGrant || cookies["PCC-GRANT"] || null;
const article = await PCCConvenienceFunctions.getArticleBySlugOrId(
slugOrId,
- publishingLevel ? publishingLevel.toString().toUpperCase() : "PRODUCTION",
+ publishingLevel
+ ? (publishingLevel.toString().toUpperCase() as "PRODUCTION" | "REALTIME")
+ : "PRODUCTION",
);
if (!article) {
@@ -60,7 +71,8 @@ export async function getServerSideProps({
if (
article.slug?.trim().length &&
- article.slug.toLowerCase() !== slugOrId?.trim().toLowerCase()
+ article.slug.toLowerCase() !== slugOrId?.trim().toLowerCase() &&
+ pantheonAPIOptions.resolvePath != null
) {
// If the article was accessed by the id rather than the slug - then redirect to the canonical
// link (mostly for SEO purposes than anything else).
diff --git a/starters/nextjs-starter-ts/pages/articles/index.tsx b/starters/nextjs-starter-ts/pages/articles/index.tsx
index f848d056..0b407b65 100644
--- a/starters/nextjs-starter-ts/pages/articles/index.tsx
+++ b/starters/nextjs-starter-ts/pages/articles/index.tsx
@@ -1,4 +1,5 @@
import {
+ Article,
ArticleWithoutContent,
PCCConvenienceFunctions,
} from "@pantheon-systems/pcc-react-sdk";
@@ -11,7 +12,17 @@ import { usePagination } from "../../hooks/usePagination";
const PAGE_SIZE = 20;
-export default function ArticlesListTemplate({ articles, totalCount, cursor }) {
+interface Props {
+ articles: Article[];
+ totalCount: number;
+ cursor: string;
+}
+
+export default function ArticlesListTemplate({
+ articles,
+ totalCount,
+ cursor,
+}: Props) {
const {
data: currentArticles,
onPageChange,
diff --git a/starters/nextjs-starter-ts/pages/authors/[author].tsx b/starters/nextjs-starter-ts/pages/authors/[author].tsx
index b08a50e6..4c7fd3b2 100644
--- a/starters/nextjs-starter-ts/pages/authors/[author].tsx
+++ b/starters/nextjs-starter-ts/pages/authors/[author].tsx
@@ -1,4 +1,5 @@
import {
+ Article,
ArticleWithoutContent,
PCCConvenienceFunctions,
} from "@pantheon-systems/pcc-react-sdk";
@@ -24,6 +25,11 @@ export default function ArticlesListTemplate({
totalCount,
cursor,
author,
+}: {
+ articles: Article[];
+ totalCount: number;
+ cursor: string;
+ author?: string;
}) {
const {
data: currentArticles,
@@ -93,7 +99,11 @@ export default function ArticlesListTemplate({
);
}
-export async function getServerSideProps({ query: { author } }) {
+export async function getServerSideProps({
+ query: { author },
+}: {
+ query: { author: string };
+}) {
const {
data: articles,
totalCount,
diff --git a/starters/nextjs-starter-ts/pages/component-preview/[id].tsx b/starters/nextjs-starter-ts/pages/component-preview/[id].tsx
index 00b8e3f7..626eb19f 100644
--- a/starters/nextjs-starter-ts/pages/component-preview/[id].tsx
+++ b/starters/nextjs-starter-ts/pages/component-preview/[id].tsx
@@ -11,8 +11,11 @@ export default function SmartComponentPreview() {
? JSON.parse(Buffer.from(attrs, "base64").toString())
: {};
- const SmartComponent =
- clientSmartComponentMap[id?.toString()]?.reactComponent;
+ const SmartComponent = id
+ ? clientSmartComponentMap[
+ id.toString() as keyof typeof clientSmartComponentMap
+ ]?.reactComponent
+ : null;
return (
diff --git a/starters/nextjs-starter-ts/pages/examples/ssg-isr/[uri].tsx b/starters/nextjs-starter-ts/pages/examples/ssg-isr/[uri].tsx
index bccc4e94..ad755ae1 100644
--- a/starters/nextjs-starter-ts/pages/examples/ssg-isr/[uri].tsx
+++ b/starters/nextjs-starter-ts/pages/examples/ssg-isr/[uri].tsx
@@ -18,7 +18,7 @@ export default function ArticlePage({ article }: ArticlePageProps) {
return (
@@ -30,17 +30,17 @@ export default function ArticlePage({ article }: ArticlePageProps) {
);
}
-export const getStaticProps: GetStaticProps<{}, { uri: string }> = async ({
- params: { uri },
-}) => {
- if (!uri) {
+export const getStaticProps: GetStaticProps<{}> = async ({ params }) => {
+ if (!params?.uri) {
return {
notFound: true,
};
}
try {
- const article = await PCCConvenienceFunctions.getArticleBySlugOrId(uri);
+ const article = await PCCConvenienceFunctions.getArticleBySlugOrId(
+ params?.uri?.toString(),
+ );
if (!article) {
return {
@@ -74,7 +74,7 @@ export const getStaticPaths: GetStaticPaths = async () => {
const pagePaths = publishedArticles.map((article) => {
const id = article.id;
- const slug = article.metadata.slug;
+ const slug = article.metadata?.slug;
// Generate both slug and id paths for each article
const paths = [
diff --git a/starters/nextjs-starter-ts/pages/examples/ssg-isr/index.tsx b/starters/nextjs-starter-ts/pages/examples/ssg-isr/index.tsx
index 64cdf320..4e860fd5 100644
--- a/starters/nextjs-starter-ts/pages/examples/ssg-isr/index.tsx
+++ b/starters/nextjs-starter-ts/pages/examples/ssg-isr/index.tsx
@@ -1,4 +1,5 @@
import {
+ Article,
ArticleWithoutContent,
PCCConvenienceFunctions,
} from "@pantheon-systems/pcc-react-sdk";
@@ -11,11 +12,17 @@ import { usePagination } from "../../../hooks/usePagination";
const PAGE_SIZE = 20;
+interface Props {
+ articles: Article[];
+ totalCount: number;
+ cursor: string;
+}
+
export default function SSGISRExampleTemplate({
articles,
totalCount,
cursor,
-}) {
+}: Props) {
const {
data: currentArticles,
onPageChange,
diff --git a/starters/nextjs-starter-ts/pages/index.tsx b/starters/nextjs-starter-ts/pages/index.tsx
index e5460876..388e270a 100644
--- a/starters/nextjs-starter-ts/pages/index.tsx
+++ b/starters/nextjs-starter-ts/pages/index.tsx
@@ -1,4 +1,7 @@
-import { PCCConvenienceFunctions } from "@pantheon-systems/pcc-react-sdk";
+import {
+ Article,
+ PCCConvenienceFunctions,
+} from "@pantheon-systems/pcc-react-sdk";
import { NextSeo } from "next-seo";
import Image from "next/image";
import Link from "next/link";
@@ -6,7 +9,7 @@ import { HomepageArticleGrid } from "../components/grid";
import Layout from "../components/layout";
import { Button } from "../components/ui/button";
-export default function Home({ articles }) {
+export default function Home({ articles }: { articles: Article[] }) {
return (
) : (
- {data.summary}
+ {data?.summary || ""}
)}
) : null}
- {isLoading || data?.searchResults?.length > 0 ? (
+ {isLoading ||
+ (data?.searchResults != null && data.searchResults.length > 0) ? (
(data?.searchResults ?? Array.from({ length: 5 })).map(
(result, index) => (
@@ -87,11 +88,11 @@ export default function Search() {
{isLoading ? (
- ) : (
+ ) : result.snippet ? (
markdownToTxt(
result.snippet.replaceAll(/{#h\..*}\n/g, "\n"),
)
- )}
+ ) : null}
diff --git a/starters/nextjs-starter-ts/tsconfig.json b/starters/nextjs-starter-ts/tsconfig.json
index a160b879..4987446c 100644
--- a/starters/nextjs-starter-ts/tsconfig.json
+++ b/starters/nextjs-starter-ts/tsconfig.json
@@ -8,7 +8,8 @@
],
"allowJs": true,
"skipLibCheck": true,
- "strict": false,
+ "strict": true,
+ "strictNullChecks": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"incremental": true,
diff --git a/starters/nextjs-starter/package.json b/starters/nextjs-starter/package.json
index 964f74b6..ac141d0d 100644
--- a/starters/nextjs-starter/package.json
+++ b/starters/nextjs-starter/package.json
@@ -36,7 +36,7 @@
"clsx": "^2.1.1",
"dotenv": "^16.4.5",
"markdown-to-txt": "^2.0.1",
- "next": "^14.2.10",
+ "next": "^14.2.15",
"next-seo": "^5.15.0",
"query-string": "^8.2.0",
"react": "18.3.1",
@@ -61,7 +61,7 @@
"tailwindcss": "^3.4.1",
"tailwindcss-animate": "^1.0.7",
"typescript": "^5.5.4",
- "vite": "^5.1.8",
+ "vite": "^5.2.14",
"vitest": "^1.3.1",
"vitest-fetch-mock": "^0.2.2"
}
diff --git a/starters/nextjs-starter/pages/component-preview/[id].tsx b/starters/nextjs-starter/pages/component-preview/[id].jsx
similarity index 85%
rename from starters/nextjs-starter/pages/component-preview/[id].tsx
rename to starters/nextjs-starter/pages/component-preview/[id].jsx
index 00b8e3f7..d4c81b4e 100644
--- a/starters/nextjs-starter/pages/component-preview/[id].tsx
+++ b/starters/nextjs-starter/pages/component-preview/[id].jsx
@@ -3,7 +3,6 @@ import { clientSmartComponentMap } from "../../components/smart-components";
export default function SmartComponentPreview() {
const router = useRouter();
-
const { id, attrs } = router.query;
const decodedAttrs =
@@ -11,8 +10,9 @@ export default function SmartComponentPreview() {
? JSON.parse(Buffer.from(attrs, "base64").toString())
: {};
- const SmartComponent =
- clientSmartComponentMap[id?.toString()]?.reactComponent;
+ const SmartComponent = id
+ ? clientSmartComponentMap[id.toString()]?.reactComponent
+ : null;
return (
diff --git a/starters/nextjs-starter/tsconfig.json b/starters/nextjs-starter/tsconfig.json
index 6db37c02..105c03a3 100644
--- a/starters/nextjs-starter/tsconfig.json
+++ b/starters/nextjs-starter/tsconfig.json
@@ -8,7 +8,8 @@
],
"allowJs": true,
"skipLibCheck": true,
- "strict": false,
+ "strict": true,
+ "strictNullChecks": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"incremental": true,