Skip to content

Commit 26cc67a

Browse files
committed
feat: Upgrade to Next.js 16, React 19, and modernize dependencies
- Upgrade Next.js from 14.2.21 to 16.0.7 - Upgrade React/React-DOM from 18.3.1 to 19.2.1 - Upgrade next-auth from 4.x to 5.0.0-beta.30 (Auth.js) - Upgrade tRPC from v10 to v11.7.2 - Upgrade TanStack React Query from v4 to v5.90.12 - Upgrade Zod from 3.x to 4.1.13 - Upgrade Sentry from 8.x to 10.29.0 - Upgrade Framer Motion from 11.x to 12.23.25 Breaking changes addressed: - Convert all page params to async (Next.js 16 requirement) - Migrate headers() to async function calls - Update next-auth to new Auth.js v5 API with handlers export - Replace 'loading' status with 'pending' (React Query v5) - Migrate ESLint from .eslintrc to flat config (eslint.config.mjs) - Update Zod error API (error.errors → error.issues) - Fix React 19 type changes (ChildNode → React.ReactNode) - Update TRPCReactProvider to accept serialized headers object
1 parent 5e5e007 commit 26cc67a

File tree

55 files changed

+3607
-2960
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+3607
-2960
lines changed

.eslintrc

Lines changed: 0 additions & 23 deletions
This file was deleted.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,6 @@ ssmSetup.zsh
6868

6969
# open-next
7070
.open-next
71+
72+
# Snyk Security Extension - AI Rules (auto-generated)
73+
.github/instructions/snyk_rules.instructions.md

.mcp.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"mcpServers": {
3+
"context7": {
4+
"command": "npx",
5+
"args": ["-y", "@upstash/context7-mcp"],
6+
"env": {
7+
"CONTEXT7_API_KEY": "ctx7sk-1d829fe1-62b2-4697-b7f4-673ae5047efd"
8+
}
9+
},
10+
"puppeteer": {
11+
"command": "npx",
12+
"args": ["-y", "puppeteer-mcp-server"],
13+
"env": {}
14+
},
15+
"next-devtools": {
16+
"command": "npx",
17+
"args": ["-y", "next-devtools-mcp@latest"]
18+
},
19+
"sequential-thinking": {
20+
"command": "npx",
21+
"args": ["-y", "@modelcontextprotocol/server-sequential-thinking"]
22+
},
23+
"Sentry": {
24+
"url": "https://mcp.sentry.dev/mcp/assemble-pro/javascript-nextjs"
25+
}
26+
}
27+
}

app/(app)/[username]/page.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ import { getServerAuthSession } from "@/server/auth";
55
import { type Metadata } from "next";
66
import { db } from "@/server/db";
77

8-
type Props = { params: { username: string } };
8+
type Props = { params: Promise<{ username: string }> };
99

10-
export async function generateMetadata({ params }: Props): Promise<Metadata> {
10+
export async function generateMetadata(props: Props): Promise<Metadata> {
11+
const params = await props.params;
1112
const username = params.username;
1213

1314
const profile = await db.query.user.findFirst({
@@ -52,11 +53,12 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
5253
};
5354
}
5455

55-
export default async function Page({
56-
params,
57-
}: {
58-
params: { username: string };
59-
}) {
56+
export default async function Page(
57+
props: {
58+
params: Promise<{ username: string }>;
59+
}
60+
) {
61+
const params = await props.params;
6062
const username = params?.username;
6163

6264
if (!username) {

app/(app)/alpha/additional-details/_actions.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export async function slideOneSubmitAction(dataInput: TypeSlideOneSchema) {
3737
return true;
3838
} catch (error) {
3939
if (error instanceof z.ZodError) {
40-
console.error("Validation error:", error.errors);
40+
console.error("Validation error:", error.issues);
4141
} else {
4242
console.error("Error updating the User model:", error);
4343
}
@@ -65,7 +65,7 @@ export async function slideTwoSubmitAction(dataInput: TypeSlideTwoSchema) {
6565
return true;
6666
} catch (error) {
6767
if (error instanceof z.ZodError) {
68-
console.error("Validation error:", error.errors);
68+
console.error("Validation error:", error.issues);
6969
} else {
7070
console.error("Error updating the User model:", error);
7171
}
@@ -97,7 +97,7 @@ export async function slideThreeSubmitAction(dataInput: TypeSlideThreeSchema) {
9797
return true;
9898
} catch (error) {
9999
if (error instanceof z.ZodError) {
100-
console.error("Validation error:", error.errors);
100+
console.error("Validation error:", error.issues);
101101
} else {
102102
console.error("Error updating the User model:", error);
103103
}

app/(app)/alpha/layout.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import React from "react";
12
import { notFound } from "next/navigation";
23

34
export const metadata = {
@@ -8,7 +9,7 @@ export const metadata = {
89
},
910
};
1011

11-
export default function Alpha({ children }: { children: ChildNode }) {
12+
export default function Alpha({ children }: { children: React.ReactNode }) {
1213
if (process.env.ALPHA || process.env.NODE_ENV === "development") {
1314
return <>{children}</>;
1415
}

app/(app)/alpha/new/[[...postIdArr]]/_client.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ const Create = () => {
4747

4848
useEffect(() => {
4949
_setUnsaved(hasUnsavedChanges);
50-
}, [hasUnsavedChanges, _setUnsaved]);
50+
// eslint-disable-next-line react-hooks/exhaustive-deps
51+
}, [hasUnsavedChanges]);
5152

5253
return (
5354
<>
@@ -197,7 +198,7 @@ const Create = () => {
197198
</div>
198199
</div>
199200
</Transition>
200-
{dataStatus === "loading" && postId && (
201+
{dataStatus === "pending" && postId && (
201202
<div className="bg-gray fixed left-0 top-0 z-40 flex h-screen w-screen items-center justify-center">
202203
<div className="z-50 flex flex-col items-center border-2 border-black bg-white px-5 py-2 opacity-100">
203204
<div className="loader-dots relative mt-2 block h-5 w-20">
@@ -236,7 +237,7 @@ const Create = () => {
236237

237238
<div className="flex items-center justify-between">
238239
<div>
239-
{saveStatus === "loading" && (
240+
{saveStatus === "pending" && (
240241
<p className="text-xs lg:text-sm">Auto-saving...</p>
241242
)}
242243
{saveStatus === "error" && savedTime && (

app/(app)/articles/[slug]/page.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@ import DOMPurify from "isomorphic-dompurify";
2020
import type { JSONContent } from "@tiptap/core";
2121
import NotFound from "@/components/NotFound/NotFound";
2222

23-
type Props = { params: { slug: string } };
23+
type Props = { params: Promise<{ slug: string }> };
2424

25-
export async function generateMetadata({ params }: Props): Promise<Metadata> {
25+
export async function generateMetadata(props: Props): Promise<Metadata> {
26+
const params = await props.params;
2627
const slug = params.slug;
2728

2829
const post = await getPost({ slug });
@@ -32,7 +33,7 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
3233
const tags = post?.tags.map((tag) => tag.tag.title);
3334

3435
if (!post) return {};
35-
const host = headers().get("host") || "";
36+
const host = (await headers()).get("host") || "";
3637
return {
3738
title: `${post.title} | by ${post.user.name} | Codú`,
3839
authors: {
@@ -77,11 +78,12 @@ const renderSanitizedTiptapContent = (jsonContent: JSONContent) => {
7778
return DOMPurify.sanitize(rawHtml);
7879
};
7980

80-
const ArticlePage = async ({ params }: Props) => {
81+
const ArticlePage = async (props: Props) => {
82+
const params = await props.params;
8183
const session = await getServerAuthSession();
8284
const { slug } = params;
8385

84-
const host = headers().get("host") || "";
86+
const host = (await headers()).get("host") || "";
8587

8688
const post = await getPost({ slug });
8789

app/(app)/articles/_client.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ const ArticlesPage = () => {
104104
Something went wrong... Please refresh your page.
105105
</div>
106106
)}
107-
{status === "loading" &&
107+
{status === "pending" &&
108108
Children.toArray(
109109
Array.from({ length: 7 }, () => {
110110
return <ArticleLoading />;
@@ -164,7 +164,7 @@ const ArticlesPage = () => {
164164
Popular topics
165165
</h3>
166166
<div className="flex flex-wrap gap-2">
167-
{tagsStatus === "loading" && <PopularTagsLoading />}
167+
{tagsStatus === "pending" && <PopularTagsLoading />}
168168
{tagsStatus === "success" &&
169169
tagsData.data.map(({ title }) => (
170170
<Link

app/(app)/company/[slug]/page.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ export const metadata = {
77
"Explore our community sponsors. Ninedots Recruitment connects top talent with leading companies in the tech industry.",
88
};
99

10-
type Props = { params: { slug: string } };
10+
type Props = { params: Promise<{ slug: string }> };
1111

12-
export default async function Page({ params }: Props) {
12+
export default async function Page(props: Props) {
13+
const params = await props.params;
1314
const { slug } = params;
1415

1516
const company = companies.find((item) => item.slug === slug.toLowerCase());

0 commit comments

Comments
 (0)