Skip to content
Open
Show file tree
Hide file tree
Changes from 6 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
5 changes: 4 additions & 1 deletion next.config.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
output: "export",
experimental: {
ppr: "incremental",
},
// output: "export",
/**
assetPrefix: "/out",
basePath: "/out", USE THIS WHEN BUILDING THE STATIC PAGE
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
"lint": "next lint"
},
"dependencies": {
"next": "14.1.4",
"react": "^18",
"react-dom": "^18"
"next": "^15.0.0-canary.46",
"react": "19.0.0-rc-e02baf6c92-20240627",
"react-dom": "19.0.0-rc-e02baf6c92-20240627"
},
"devDependencies": {
"@types/node": "^20",
Expand Down
51 changes: 51 additions & 0 deletions src/app/home/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import Home from "@/components/Home";
// import type { Post } from "@/types/PostProps";
import Link from "next/link";

export default async function PostPage() {
// const response = await fetch("https://jsonplaceholder.typicode.com/posts");

// const posts: Post[] = await response.json();
const todayDate = new Date().toLocaleString();

return (
<div className="min-h-screen bg-gray-100">
<header className="bg-white shadow">
<div className="container mx-auto px-4 py-6">
<h1 className="text-2xl font-bold text-gray-800">Post Title</h1>
<Link href="/" className="text-blue-600">
Testing Home!!!!! {todayDate}
</Link>
</div>
</header>
<main className="container mx-auto px-4 py-6">
<Home />
{/* {posts.length > 0 ? (
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
{posts.map((post: any) => (
<Link
href={`/posts/${post.id}`}
key={post.id}
className="rounded-lg bg-white p-6 shadow"
>
<h2 className="text-lg font-bold text-gray-800">
{post.title}
</h2>
<p className="text-gray-700">{post.body}</p>
</Link>
))}
</div>
) : (
<p className="text-gray-700">No posts found.</p>
)} */}
</main>
<footer className="bg-gray-200">
<div className="container mx-auto px-4 py-6">
<p className="text-center text-gray-600">
© 2022 Your Website. All rights reserved.
</p>
</div>
</footer>
</div>
);
}
9 changes: 8 additions & 1 deletion src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import { Suspense } from "react";

const inter = Inter({ subsets: ["latin"] });

export const experimental_ppr = true;

export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
Expand All @@ -16,7 +19,11 @@ export default function RootLayout({
}>) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
<body className={inter.className}>
<Suspense fallback={<div>Loading in app/layout...</div>}>
{children}
</Suspense>
</body>
</html>
);
}
9 changes: 9 additions & 0 deletions src/app/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from "react";

export default function Loading() {
return (
<div className={"flex h-96 items-center justify-center "}>
<div className={"loading-dots !w-10"}></div>
</div>
);
}
14 changes: 14 additions & 0 deletions src/app/not-found.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from "react";

export const dynamic = "force-static";

export default async function NotFound() {
const todayDate = new Date().toLocaleString();

return (
<div>
NotFound at top level! {todayDate}
<a href="/">Go back home.</a>
</div>
);
}
8 changes: 6 additions & 2 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import Link from "next/link";

export default function Home() {
const todayDate = new Date().toLocaleString();

return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<div className="z-10 w-full max-w-5xl items-center justify-between font-mono text-sm lg:flex">
<h1 className="text-2xl font-bold text-blue-600">Hello World</h1>
<h1 className="text-2xl font-bold text-blue-600">
Hello World {todayDate}
</h1>
<Link className="hover:text-blue-600" href="/posts">
See posts
See posts. {todayDate}
</Link>
</div>
</main>
Expand Down
29 changes: 29 additions & 0 deletions src/app/posts/[postId]/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import { Suspense } from "react";
// import "./globals.css";

const inter = Inter({ subsets: ["latin"] });

export const experimental_ppr = true;

export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={inter.className}>
<Suspense fallback={<div>Loading in [postid]/layout...</div>}>
{children}
</Suspense>
</body>
</html>
);
}
9 changes: 9 additions & 0 deletions src/app/posts/[postId]/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from "react";

export default function Loading() {
return (
<div className={"flex h-96 items-center justify-center "}>
<div className={"loading-dots !w-10"}></div>
</div>
);
}
67 changes: 53 additions & 14 deletions src/app/posts/[postId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,70 @@
import type { Post } from "@/types/PostProps";
import Link from "next/link";
import { Suspense } from "react";

const isPostCached = (postId: string) => {
return ["1", "2", "3", "4", "5", "6"].includes(postId);
};

export async function generateStaticParams() {
const posts: Post[] = await fetch(
"https://jsonplaceholder.typicode.com/posts",
).then((res) => res.json());
// only pre render the first post, but have a good loading experience for the rest
// const isPostPreBuilt = (postId: string) => {
// return ["1", "2", "3", "7", "8", "9"].includes(postId);
// };
return [
{ postId: "1" },
{ postId: "2" },
{ postId: "3" },
{ postId: "7" },
{ postId: "8" },
{ postId: "9" },
];
// const posts: Post[] = await fetch(
// "https://jsonplaceholder.typicode.com/posts",
// ).then((res) => res.json());

return posts.map((post) => ({
postId: post.id.toString(),
}));
// return posts
// .map((post) => ({
// postId: post.id.toString(),
// }))
// .slice(0, 5);
}

export default async function Post({ params }: { params: { postId: string } }) {
const PostItem = async ({ postId }: { postId: string }) => {
const response = await fetch(
`https://jsonplaceholder.typicode.com/posts/${params.postId}`,
`https://jsonplaceholder.typicode.com/posts/${postId}`,
{
cache: isPostCached(postId) ? "default" : "no-store",
// cache: "no-store",
// cache: "default",
},
);

const post: Post = await response.json();
await new Promise((resolve) => setTimeout(resolve, 2000));

const todayDate = new Date().toLocaleString();

return (
<div className="w-1/2 rounded bg-white p-10 shadow-lg">
<h1 className="mb-4 text-4xl font-bold text-blue-600">
{post.title + todayDate}
</h1>
<p className="text-gray-700">{post.body}</p>
</div>
);
};

export default function Post({ params }: { params: { postId: string } }) {
const datewithSeconds = new Date().toLocaleString();
const exactDate = Date.now().toString();

return (
<div className="flex min-h-screen flex-col items-center justify-center bg-gray-100">
<div className="w-1/2 rounded bg-white p-10 shadow-lg">
<h1 className="mb-4 text-4xl font-bold text-blue-600">{post.title}</h1>
<p className="text-gray-700">{post.body}</p>
</div>
<Suspense fallback={<div>loading............</div>}>
<PostItem postId={params.postId} />
</Suspense>
<Link className="mt-4 hover:text-blue-500" href="/posts">
Go Back
Go Back {datewithSeconds} {exactDate}
</Link>
</div>
);
Expand Down
9 changes: 9 additions & 0 deletions src/app/posts/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from "react";

export default function Loading() {
return (
<div className={"flex h-96 items-center justify-center "}>
<div className={"loading-dots !w-10"}></div>
</div>
);
}
14 changes: 14 additions & 0 deletions src/app/posts/not-found.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from "react";

export const dynamic = "force-static";

export default async function NotFound() {
const todayDate = new Date().toLocaleString();

return (
<div>
NotFound at in posts! {todayDate}
<a href="/">Go back home.</a>
</div>
);
}
Loading