#I can't build in Next Js 15.0.2 due to params in a page (dynamic segment)

41 messages · Page 1 of 1 (latest)

errant mason
#

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 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:


.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://discord.com/channels/752553802359505017/1299939488654561361>

I'm being unable to solve the problem.
What I'm doing wrong ?
mellow gardenBOT
#

🔎 This post has been indexed in our web forum and will be seen by search engines so other users can find it outside Discord

🕵️ Your user profile is private by default and won't be visible to users outside Discord, if you want to be visible in the web forum you can add the "Public Profile" role in id:customize

✅ You can mark a message as the answer for your post with Right click -> Apps -> Mark Solution
(if you don't see the option, try refreshing Discord with Ctrl + R)

tight kraken
#

That is a error in types I believe

#

Can you send type of BlogPost?

errant mason
#

Hi @tight kraken !
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.

tight kraken
#

if build is running on prod, have you added env variables?

errant mason
#

I've used this to connect.
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;
tight kraken
#

are you running build locally?

errant mason
#

pnpm run build
yep 😀

tight kraken
#

I'm unsure about drizzle can you try using as when setting types, and see if you still get the error

#

and also console log the item

errant mason
#

Oh... I'm seeing next/server has this:
export type { UnsafeUnwrappedParams } from 'next/dist/server/request/params'

tight kraken
#

No, in db operation

#

When you read from db

errant mason
#

This ?
const post = await db.select().from(Post).where(eq(Post.slug, slug)).limit(1);

tight kraken
#

Yup, try to set as type. Also console log the post

errant mason
#

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 .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 😅

prisma glade
errant mason
#

oh maybe not the type, just the schema.... but meh it work on dev.

prisma glade
#

The bug is not relevant to drizzle or blog content or anything

#

Paste the prop type of app/blog/page/[page]/pags.tsx here

errant mason
#

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>
  );
}

prisma glade
errant mason
#

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')
 ELIFECYCLECommand 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)

prisma glade
mellow gardenBOT