└── nextjs-demo
├── .eslintrc.json
├── .gitignore
├── README.md
├── next.config.ts
├── package-lock.json
├── package.json
├── postcss.config.mjs
├── public
├── file.svg
├── globe.svg
├── next.svg
├── vercel.svg
└── window.svg
├── src
├── app
│ ├── (auth)
│ │ ├── forgot-password
│ │ │ └── page.tsx
│ │ ├── login
│ │ │ └── page.tsx
│ │ └── register
│ │ │ └── page.tsx
│ ├── about
│ │ └── page.tsx
│ ├── blog
│ │ └── first-post
│ │ │ └── page.tsx
│ ├── components
│ │ ├── counter.tsx
│ │ ├── greet.tsx
│ │ └── navigation.tsx
│ ├── favicon.ico
│ ├── fonts
│ │ ├── GeistMonoVF.woff
│ │ └── GeistVF.woff
│ ├── globals.css
│ ├── layout.tsx
│ ├── mock-users
│ │ └── page.tsx
│ ├── page.tsx
│ ├── products
│ │ └── [id]
│ │ │ ├── layout.tsx
│ │ │ └── page.tsx
│ └── users
│ │ ├── [id]
│ │ └── route.ts
│ │ └── route.ts
└── middleware.ts
├── tailwind.config.ts
└── tsconfig.json
/nextjs-demo/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["next/core-web-vitals", "next/typescript"]
3 | }
4 |
--------------------------------------------------------------------------------
/nextjs-demo/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.*
7 | .yarn/*
8 | !.yarn/patches
9 | !.yarn/plugins
10 | !.yarn/releases
11 | !.yarn/versions
12 |
13 | # testing
14 | /coverage
15 |
16 | # next.js
17 | /.next/
18 | /out/
19 |
20 | # production
21 | /build
22 |
23 | # misc
24 | .DS_Store
25 | *.pem
26 |
27 | # debug
28 | npm-debug.log*
29 | yarn-debug.log*
30 | yarn-error.log*
31 |
32 | # env files (can opt-in for commiting if needed)
33 | .env*
34 |
35 | # vercel
36 | .vercel
37 |
38 | # typescript
39 | *.tsbuildinfo
40 | next-env.d.ts
41 |
--------------------------------------------------------------------------------
/nextjs-demo/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | # or
12 | pnpm dev
13 | # or
14 | bun dev
15 | ```
16 |
17 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
18 |
19 | You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
20 |
21 | This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
22 |
23 | ## Learn More
24 |
25 | To learn more about Next.js, take a look at the following resources:
26 |
27 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
29 |
30 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
31 |
32 | ## Deploy on Vercel
33 |
34 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
35 |
36 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
37 |
--------------------------------------------------------------------------------
/nextjs-demo/next.config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from "next";
2 |
3 | const nextConfig: NextConfig = {
4 | /* config options here */
5 | };
6 |
7 | export default nextConfig;
8 |
--------------------------------------------------------------------------------
/nextjs-demo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nextjs-demo",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "@clerk/nextjs": "^6.0.2",
13 | "next": "15.0.1",
14 | "react": "19.0.0-rc-69d4b800-20241021",
15 | "react-dom": "19.0.0-rc-69d4b800-20241021"
16 | },
17 | "devDependencies": {
18 | "@types/node": "^20",
19 | "@types/react": "^18",
20 | "@types/react-dom": "^18",
21 | "eslint": "^8",
22 | "eslint-config-next": "15.0.1",
23 | "postcss": "^8",
24 | "tailwindcss": "^3.4.1",
25 | "typescript": "^5"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/nextjs-demo/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/nextjs-demo/public/file.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/nextjs-demo/public/globe.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/nextjs-demo/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/nextjs-demo/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/nextjs-demo/public/window.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/nextjs-demo/src/app/(auth)/forgot-password/page.tsx:
--------------------------------------------------------------------------------
1 | export default function ForgotPassword() {
2 | return
Forgot Password
;
3 | }
4 |
--------------------------------------------------------------------------------
/nextjs-demo/src/app/(auth)/login/page.tsx:
--------------------------------------------------------------------------------
1 | export default function Login() {
2 | return Login
;
3 | }
4 |
--------------------------------------------------------------------------------
/nextjs-demo/src/app/(auth)/register/page.tsx:
--------------------------------------------------------------------------------
1 | export default function Register() {
2 | return Register
;
3 | }
4 |
--------------------------------------------------------------------------------
/nextjs-demo/src/app/about/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { useRouter } from "next/navigation";
3 |
4 | export default function About() {
5 | const router = useRouter();
6 | return (
7 | <>
8 | About Us
9 |
15 | >
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/nextjs-demo/src/app/blog/first-post/page.tsx:
--------------------------------------------------------------------------------
1 | export default function FirstPost() {
2 | return First blog post
;
3 | }
4 |
--------------------------------------------------------------------------------
/nextjs-demo/src/app/components/counter.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { useState } from "react";
3 |
4 | export const Counter = () => {
5 | console.log("Counter component");
6 | const [count, setCount] = useState(0);
7 |
8 | return (
9 |
10 | );
11 | };
12 |
--------------------------------------------------------------------------------
/nextjs-demo/src/app/components/greet.tsx:
--------------------------------------------------------------------------------
1 | export const Greet = () => {
2 | console.log("Greet component");
3 | return Greet component
;
4 | };
5 |
--------------------------------------------------------------------------------
/nextjs-demo/src/app/components/navigation.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import Link from "next/link";
3 | import { usePathname } from "next/navigation";
4 | import { SignInButton, SignedIn, SignedOut, UserButton } from "@clerk/nextjs";
5 |
6 | export const Navigation = () => {
7 | const pathname = usePathname();
8 | return (
9 |
41 | );
42 | };
43 |
--------------------------------------------------------------------------------
/nextjs-demo/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gopinav/Next.js-15-Crash-Course/7deee20c83aa9a5c37330bc48cc412c31b3b1793/nextjs-demo/src/app/favicon.ico
--------------------------------------------------------------------------------
/nextjs-demo/src/app/fonts/GeistMonoVF.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gopinav/Next.js-15-Crash-Course/7deee20c83aa9a5c37330bc48cc412c31b3b1793/nextjs-demo/src/app/fonts/GeistMonoVF.woff
--------------------------------------------------------------------------------
/nextjs-demo/src/app/fonts/GeistVF.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gopinav/Next.js-15-Crash-Course/7deee20c83aa9a5c37330bc48cc412c31b3b1793/nextjs-demo/src/app/fonts/GeistVF.woff
--------------------------------------------------------------------------------
/nextjs-demo/src/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | :root {
6 | --background: #ffffff;
7 | --foreground: #171717;
8 | }
9 |
10 | @media (prefers-color-scheme: dark) {
11 | :root {
12 | --background: #0a0a0a;
13 | --foreground: #ededed;
14 | }
15 | }
16 |
17 | body {
18 | color: var(--foreground);
19 | background: var(--background);
20 | font-family: Arial, Helvetica, sans-serif;
21 | }
22 |
--------------------------------------------------------------------------------
/nextjs-demo/src/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from "next";
2 | import localFont from "next/font/local";
3 | import { ClerkProvider } from "@clerk/nextjs";
4 | import "./globals.css";
5 | import { Navigation } from "./components/navigation";
6 |
7 | const geistSans = localFont({
8 | src: "./fonts/GeistVF.woff",
9 | variable: "--font-geist-sans",
10 | weight: "100 900",
11 | });
12 | const geistMono = localFont({
13 | src: "./fonts/GeistMonoVF.woff",
14 | variable: "--font-geist-mono",
15 | weight: "100 900",
16 | });
17 |
18 | export const metadata: Metadata = {
19 | title: "Create Next App",
20 | description: "Generated by create next app",
21 | };
22 |
23 | export default function RootLayout({
24 | children,
25 | }: Readonly<{
26 | children: React.ReactNode;
27 | }>) {
28 | return (
29 |
30 |
31 |
34 |
38 | {children}
39 |
42 |
43 |
44 |
45 | );
46 | }
47 |
--------------------------------------------------------------------------------
/nextjs-demo/src/app/mock-users/page.tsx:
--------------------------------------------------------------------------------
1 | import { revalidatePath } from "next/cache";
2 | import { auth, currentUser } from "@clerk/nextjs/server";
3 |
4 | type MockUser = {
5 | id: number;
6 | name: string;
7 | };
8 |
9 | export default async function Users() {
10 | const authObj = await auth();
11 | const userObj = await currentUser();
12 |
13 | console.log({ authObj });
14 | console.log({ userObj });
15 |
16 | const res = await fetch("https://66974b0d02f3150fb66d25c5.mockapi.io/users");
17 | const users = await res.json();
18 |
19 | async function addUser(formData: FormData) {
20 | "use server";
21 | const name = formData.get("name");
22 | const res = await fetch(
23 | "https://66974b0d02f3150fb66d25c5.mockapi.io/users",
24 | {
25 | method: "POST",
26 | headers: {
27 | "Content-Type": "application/json",
28 | },
29 | body: JSON.stringify({ name }),
30 | }
31 | );
32 | const newUser = await res.json();
33 | console.log(newUser);
34 | revalidatePath("/mock-users");
35 | }
36 |
37 | return (
38 |
39 |
53 |
54 | {users.map((user: MockUser) => (
55 |
59 | {user.name}
60 |
61 | ))}
62 |
63 |
64 | );
65 | }
66 |
--------------------------------------------------------------------------------
/nextjs-demo/src/app/page.tsx:
--------------------------------------------------------------------------------
1 | import Image from "next/image";
2 | import { Greet } from "./components/greet";
3 | import { Counter } from "./components/counter";
4 | export default function Home() {
5 | return (
6 |
7 |
8 |
16 |
17 |
18 |
19 | -
20 | Get started by editing{" "}
21 |
22 | src/app/page.tsx
23 |
24 | .
25 |
26 | - Save and see your changes instantly.
27 |
28 |
29 |
54 |
55 |
102 |
103 | );
104 | }
105 |
--------------------------------------------------------------------------------
/nextjs-demo/src/app/products/[id]/layout.tsx:
--------------------------------------------------------------------------------
1 | export default function ProductLayout({
2 | children,
3 | }: {
4 | children: React.ReactNode;
5 | }) {
6 | return (
7 |
8 | {children}
9 |
10 |
Featured products section
11 |
12 |
13 | );
14 | }
15 |
--------------------------------------------------------------------------------
/nextjs-demo/src/app/products/[id]/page.tsx:
--------------------------------------------------------------------------------
1 | export default async function Product({ params }: { params: { id: string } }) {
2 | const { id } = await params;
3 | return Product: {id}
;
4 | }
5 |
--------------------------------------------------------------------------------
/nextjs-demo/src/app/users/[id]/route.ts:
--------------------------------------------------------------------------------
1 | import { users } from "../route";
2 |
3 | export async function GET(
4 | _request: Request,
5 | { params }: { params: { id: string } }
6 | ) {
7 | const { id } = await params;
8 | const user = users.find((user) => user.id === parseInt(id));
9 | return Response.json(user);
10 | }
11 |
--------------------------------------------------------------------------------
/nextjs-demo/src/app/users/route.ts:
--------------------------------------------------------------------------------
1 | export const users = [
2 | { id: 1, name: "John Doe" },
3 | { id: 2, name: "Jane Doe" },
4 | ];
5 |
6 | export async function GET() {
7 | return Response.json(users);
8 | }
9 |
10 | export async function POST(request: Request) {
11 | const user = await request.json();
12 | const newUser = { id: users.length + 1, name: user.name };
13 | users.push(newUser);
14 | return new Response(JSON.stringify(newUser), {
15 | headers: { "Content-Type": "application/json" },
16 | status: 201,
17 | });
18 | }
19 |
--------------------------------------------------------------------------------
/nextjs-demo/src/middleware.ts:
--------------------------------------------------------------------------------
1 | import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";
2 |
3 | const isProtectedRoute = createRouteMatcher(["/mock-users(.*)"]);
4 |
5 | export default clerkMiddleware(async (auth, req) => {
6 | if (isProtectedRoute(req)) await auth.protect();
7 | });
8 |
9 | export const config = {
10 | matcher: [
11 | // Skip Next.js internals and all static files, unless found in search params
12 | "/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)",
13 | // Always run for API routes
14 | "/(api|trpc)(.*)",
15 | ],
16 | };
17 |
--------------------------------------------------------------------------------
/nextjs-demo/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from "tailwindcss";
2 |
3 | const config: Config = {
4 | content: [
5 | "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
6 | "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
7 | "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
8 | ],
9 | theme: {
10 | extend: {
11 | colors: {
12 | background: "var(--background)",
13 | foreground: "var(--foreground)",
14 | },
15 | },
16 | },
17 | plugins: [],
18 | };
19 | export default config;
20 |
--------------------------------------------------------------------------------
/nextjs-demo/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2017",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "noEmit": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "bundler",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve",
15 | "incremental": true,
16 | "plugins": [
17 | {
18 | "name": "next"
19 | }
20 | ],
21 | "paths": {
22 | "@/*": ["./src/*"]
23 | }
24 | },
25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26 | "exclude": ["node_modules"]
27 | }
28 |
--------------------------------------------------------------------------------