I can't build in Next Js 15.0.2 due to params in a page (dynamic segment)
Answered
West African Crocodile posted this in #help-forum
West African CrocodileOP
Hi there,
I searched other threads before creating. Found similar questions. But the approved solutions are not working for me. So I'm creating mine.
This code works while I do
But If I do
I also tried with things like
And matched how it was done here:
https://nextjs.org/docs/canary/app/building-your-application/upgrading/version-15#asynchronous-page
https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes
https://nextjs-forum.com/post/1299939488654561361
I'm being unable to solve the problem.
What I'm doing wrong ?
I searched other threads before creating. Found similar questions. But the approved solutions are not working for me. So I'm creating mine.
This code works while I do
pnpm run dev
, I can see the post loaded.// app/blog/[slug]/page.tsx
import { notFound } from "next/navigation";
import BlogPost from "@/components/BlogPost";
import db from "@/db/index";
import { Post } from "@/db/schema";
import { eq } from "drizzle-orm";
type Props = {
params: Promise<{ slug: string }>;
};
export default async function Page(props: Props) {
const { slug } = await props.params;
const post = await db.select().from(Post).where(eq(Post.slug, slug)).limit(1);
if (!post.length) {
notFound();
}
return <BlogPost post={post[0]} />;
}
But If I do
pnpm run build
then I get this error: Linting and checking validity of types .Failed to compile.
.next/types/app/blog/page/[page]/page.ts:34:29
Type error: Type '{ params: { page: string; }; }' does not satisfy the constraint 'PageProps'.
Types of property 'params' are incompatible.
Type '{ page: string; }' is missing the following properties from type 'Promise<any>': then, catch, finally, [Symbol.toStringTag]
32 |
33 | // Check the prop type of the entry function
> 34 | checkFields<Diff<PageProps, FirstArg<TEntry['default']>, 'default'>>()
| ^
35 |
36 | // Check the arguments and return type of the generateMetadata function
37 | if ('generateMetadata' in entry) {
ELIFECYCLE Command failed with exit code 1.
I also tried with things like
params: Promise<{slug: string}> | {slug:string}
And matched how it was done here:
https://nextjs.org/docs/canary/app/building-your-application/upgrading/version-15#asynchronous-page
https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes
https://nextjs-forum.com/post/1299939488654561361
I'm being unable to solve the problem.
What I'm doing wrong ?
39 Replies
That is a error in types I believe
Can you send type of
BlogPost
?West African CrocodileOP
Hi @Anay-208 !
I'm using drizzle orm (or trying 😅 )
So the types for the
I'm "glob importing" it from
And this is the schema:
I thought my schema types should have something to do with the error... but v0.dev told me it was a problem with it being awaited and so... So I got pretty confused with these new async changes I think.
I'm using drizzle orm (or trying 😅 )
So the types for the
BlogPost
are the inferred types from the Schema.import { SelectPost } from "@/db/schema";
interface BlogPostProps {
post: SelectPost;
}
export default function BlogPost({ post }: BlogPostProps) {
I'm "glob importing" it from
src\db\schema\index.ts
with export * from "./post";
And this is the schema:
import { InferSelectModel, InferInsertModel, sql } from "drizzle-orm";
import { pgTable as table } from "drizzle-orm/pg-core";
import * as t from "drizzle-orm/pg-core";
const timestamps = {
updatedAt: t.timestamp({ withTimezone: true, mode: "string" }),
createdAt: t
.timestamp({ withTimezone: true, mode: "string" })
.defaultNow()
.notNull(),
deletedAt: t.timestamp({ withTimezone: true, mode: "string" }),
};
export const Post = table(
"Post",
{
id: t.integer().primaryKey().generatedAlwaysAsIdentity(),
title: t.text().notNull(),
slug: t.text().notNull().unique(),
excerpt: t.text().notNull(),
author: t.text().notNull(),
category: t.text().notNull(),
tags: t
.text()
.array()
.notNull()
.default(sql`ARRAY[]::text[]`),
readingTime: t.integer().notNull(),
content: t.text().notNull(),
components: t
.text()
.array()
.notNull()
.default(sql`ARRAY[]::text[]`),
...timestamps,
},
(table) => {
return {
slugIndex: t.uniqueIndex("slug_idx").on(table.slug),
titleIndex: t.index("title_idx").on(table.title),
};
}
);
export type SelectPost = InferSelectModel<typeof Post>;
export type InsertPost = InferInsertModel<typeof Post>;
I thought my schema types should have something to do with the error... but v0.dev told me it was a problem with it being awaited and so... So I got pretty confused with these new async changes I think.
if build is running on prod, have you added env variables?
West African CrocodileOP
I've used this to connect.
My
I was just trying to build on localhost
My
.env
just have DATABASE_URL=....the connection string....
I was just trying to build on localhost
import "dotenv/config";
import { drizzle } from "drizzle-orm/node-postgres";
import { Pool } from "pg";
import * as schema from "@/db/schema";
const pool = new Pool({
connectionString: process.env.DATABASE_URL!,
});
const db = drizzle(pool, {
schema,
logger: true,
});
// export type db = typeof db;
export default db;
are you running build locally?
West African CrocodileOP
pnpm run build
yep 😀
I'm unsure about drizzle can you try using
as
when setting types, and see if you still get the errorand also console log the item
West African CrocodileOP
Uhmm... I only saw the usage of
https://nextjs.org/docs/canary/app/building-your-application/upgrading/version-15#asynchronous-page
Like:
There's also something similar for
Is this what you mean ? There should be an
as
here:https://nextjs.org/docs/canary/app/building-your-application/upgrading/version-15#asynchronous-page
Like:
const cookieStore = cookies() as unknown as UnsafeUnwrappedCookies
There's also something similar for
draftMode
and headers
but not for page, at least there.Is this what you mean ? There should be an
UnsafeUnwrappedPage
too ? I'm not really sure what should use for as
in my case.Oh... I'm seeing
next/server
has this:export type { UnsafeUnwrappedParams } from 'next/dist/server/request/params'
No, in db operation
When you read from db
West African CrocodileOP
This ?
const post = await db.select().from(Post).where(eq(Post.slug, slug)).limit(1);
Yup, try to set as type. Also console log the post
West African CrocodileOP
I tried to use
as Post
and as SelectPost
but doesn't seem to like it 😅Light theme sorry 😅
In theory, with drizzle, I'm already passing the type, in the
In fact, I can load the page with the data when running with
.from(Post)
It's all what it needs to make the select.In fact, I can load the page with the data when running with
pnpm run dev
mid english, mid spanish 😅
The bug is in app/blog/page/[page]/page.tsx, not app/blog/[slug]/page.tsx
West African CrocodileOP
oh maybe not the type, just the schema.... but meh it work on dev.
The bug is not relevant to drizzle or blog content or anything
Paste the prop type of app/blog/page/[page]/pags.tsx here
West African CrocodileOP
ohhhh
the route is other : /
It's true I have some different routes, where I'm trying different things.
Ah yes, this is where I tried to implement a pagination.
import { PaginationComponent } from "@/components/Pagination";
import { getBlogPosts } from "@/lib/blog";
export default async function BlogPage({
params,
}: {
params: { page: string };
}) {
const { page } = await params;
const currentPage = parseInt(page, 10) || 1;
const { posts, totalPages } = await getBlogPosts(currentPage, 2);
return (
<div>
{/* Render your blog posts here */}
<ul className="flex flex-col gap-4">
{posts.map((post, index) => (
<li key={index}>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
<p>Published on: {new Date(post.createdAt).toLocaleDateString()}</p>
{post.updatedAt && (
<p>Updated on: {new Date(post.updatedAt).toLocaleDateString()}</p>
)}
<p>Category: {post.category}</p>
<p>Author: {post.author}</p>
<p>Reading time: {post.readingTime}</p>
<p>Tags: {post.tags.join(", ")}</p>
</li>
))}
</ul>
<PaginationComponent
currentPage={currentPage}
totalPages={totalPages}
maxPageNumbers={3}
/>
</div>
);
}
params: Promise<{ page: string }> instead of { page: string }
Answer
West African CrocodileOP
I'm trying to build after changing it
haha my app feels like a mine field atm....
Linting and checking validity of types ..Failed to compile.
.next/types/app/post/page.ts:2:24
Type error: File 'C:/dev/nextjs/next-stable-pnpm/src/app/post/page.tsx' is not a module.
1 | // File: C:\dev\nextjs\next-stable-pnpm\src\app\post\page.tsx
> 2 | import * as entry from '../../../../src/app/post/page.js'
| ^
3 | import type { ResolvingMetadata, ResolvingViewport } from 'next/dist/lib/metadata/types/metadata-interface.js'
4 |
5 | type TEntry = typeof import('../../../../src/app/post/page.js')
ELIFECYCLE Command failed with exit code 1.
another file....
so my initial problem is solved I guess
I need 5 min, then I could check further (bit busy)
Different bug, different post. Open a new post if you need help. Though the bug is in app/post/page.tsx, go there and try to see if something is wrong first
West African CrocodileOP
Sure, many thanks for helping me 🙂 both of you !