Ugrás a tartalomra
Vissza a bloghoz
Tutorial

Teljes útmutató: Full Stack fejlesztés Next.js 14-gyel

2025. január 8.28 perc olvasás
#Next.js#Full Stack#API
Teljes útmutató: Full Stack fejlesztés Next.js 14-gyel

A Next.js 14 megjelenésével a full stack fejlesztés soha nem volt ilyen elérhető. Ebben a cikkben nem elméleti példákat mutatok – egy valódi, teljes értékű alkalmazást építünk a semmiből: felhasználókezelés, adatbázis, hitelesítés, űrlapok, valós idejű frissítések. Végigmegyünk minden lépésen, úgyhogy kapcsold be a kedvenc IDE-det, és vágjunk bele!

Újságírói illusztráció

Miért pont Next.js 14?

A Next.js az utóbbi években a React-alapú alkalmazások királya lett. A 14-es verzióval azonban a Vercel csapata túllépett a „React keretrendszer” címkén – a Next.js immár egy teljes értékű full stack platform, amely versenyképes olyan gigászokkal, mint a Ruby on Rails, a Laravel vagy a Django.

Mit nyújt a Next.js 14?

  • 🔥 Server Components – alapértelmezésben szerveroldali renderelés, nulla kliensoldali JS
  • 🔥 Server Actions – API endpoint-ok írása nélküli adatmódosítás
  • 🔥 App Router – fájlalapú útvonalak, layout-ok, párhuzamos útvonalak
  • 🔥 Beépített optimalizálások – képek, betűtípusok, szkriptek automatikus kezelése
  • 🔥 Zero-config TypeScript, ESLint, Tailwind – azonnal használható

Az alábbiakban egy teljes alkalmazást építünk, amelyben a felhasználók regisztrálhatnak, bejelentkezhetnek, és blogbejegyzéseket írhatnak. Mindezt egyetlen kódbázisban, a backend és frontend szétválasztása nélkül.

1. Projekt inicializálás

Indítsd el a terminált, és futtasd:

npx create-next-app@latest my-fullstack-app
# Válaszd az alábbiakat:
# - TypeScript: Yes
# - ESLint: Yes
# - Tailwind CSS: Yes
# - src/ directory: Yes
# - App Router: Yes

Lépj be a mappába: cd my-fullstack-app

2. Adatbázis beállítása Prisma-val

A Prisma a legjobb választás Next.js mellé – típusbiztos, egyszerű és erős.

npm install prisma --save-dev
npx prisma init

A .env fájlban állítsd be az adatbázis URL-t (itt PostgreSQL-t használok, de SQLite is működik fejlesztésben):

DATABASE_URL="postgresql://postgres:password@localhost:5432/myapp"

Szerkesszük a prisma/schema.prisma fájlt:

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
  id        String   @id @default(cuid())
  email     String   @unique
  name      String
  password  String   // később hasheljük
  posts     Post[]
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

Újságírói illusztráció
model Post { id String @id @default(cuid()) title String content String published Boolean @default(false) authorId String author User @relation(fields: [authorId], references: [id]) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt }

Futtasd a migrációt:

npx prisma migrate dev --name init
npx prisma generate

Hozz létre egy lib/prisma.ts fájlt a kliens inicializálásához:

import { PrismaClient } from '@prisma/client'

const globalForPrisma = global as unknown as { prisma: PrismaClient }

export const prisma = globalForPrisma.prisma || new PrismaClient()

if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma

3. Hitelesítés NextAuth-dal (Auth.js)

Telepítsd a NextAuth-ot:

npm install next-auth @auth/prisma-adapter
npm install bcryptjs
npm install --save-dev @types/bcryptjs

Készítsd el a app/api/auth/[...nextauth]/route.ts fájlt:

import NextAuth from "next-auth"
import CredentialsProvider from "next-auth/providers/credentials"
import { PrismaAdapter } from "@auth/prisma-adapter"
import { prisma } from "@/lib/prisma"
import bcrypt from "bcryptjs"

const handler = NextAuth({
  adapter: PrismaAdapter(prisma),
  providers: [
    CredentialsProvider({
      name: "credentials",
      credentials: {
        email: { label: "Email", type: "email" },
        password: { label: "Jelszó", type: "password" }
      },
      async authorize(credentials) {
        if (!credentials?.email || !credentials?.password) return null
        
        const user = await prisma.user.findUnique({
          where: { email: credentials.email }
        })
        
        if (!user) return null
        
        const isValid = await bcrypt.compare(credentials.password, user.password)
        if (!isValid) return null
        
        return { id: user.id, email: user.email, name: user.name }
      }
    })
  ],
  session: { strategy: "jwt" },
  pages: { signIn: "/login" },
  callbacks: {
    async jwt({ token, user }) {
      if (user) token.id = user.id
      return token
    },
    async session({ session, token }) {
      if (session.user) session.user.id = token.id as string
      return session
    }
  }
})

Újságírói illusztráció
export { handler as GET, handler as POST }

Regisztrációhoz készíts egy Server Action-t a app/actions/auth.ts fájlban:

'use server'
import { prisma } from "@/lib/prisma"
import bcrypt from "bcryptjs"
import { redirect } from "next/navigation"

export async function register(formData: FormData) {
  const email = formData.get("email") as string
  const name = formData.get("name") as string
  const password = formData.get("password") as string
  
  const existingUser = await prisma.user.findUnique({ where: { email } })
  if (existingUser) throw new Error("Ez az email már regisztrálva van")
  
  const hashedPassword = await bcrypt.hash(password, 10)
  
  await prisma.user.create({
    data: { email, name, password: hashedPassword }
  })
  
  redirect("/login")
}

4. Blogbejegyzések CRUD műveletei

Készítsünk egy űrlapot új poszt létrehozásához Server Actions segítségével (app/dashboard/new-post/page.tsx):

import { getServerSession } from "next-auth"
import { redirect } from "next/navigation"
import { prisma } from "@/lib/prisma"
import { revalidatePath } from "next/cache"

async function createPost(formData: FormData) {
  'use server'
  const session = await getServerSession()
  if (!session?.user) throw new Error("Nem vagy bejelentkezve")
  
  const title = formData.get("title") as string
  const content = formData.get("content") as string
  
  await prisma.post.create({
    data: {
      title,
      content,
      authorId: session.user.id,
      published: true
    }
  })
  
  revalidatePath("/dashboard")
  redirect("/dashboard")
}

export default function NewPostPage() {
  return (
    <form action={createPost} className="space-y-4">
      <div>
        <label htmlFor="title" className="block text-sm font-medium">Cím</label>
        <input type="text" name="title" id="title" required className="mt-1 block w-full rounded-md border-gray-300 shadow-sm" />
      </div>
      <div>
        <label htmlFor="content" className="block text-sm font-medium">Tartalom</label>
        <textarea name="content" id="content" rows={10} required className="mt-1 block w-full rounded-md border-gray-300 shadow-sm" />
      </div>
      <button type="submit" className="bg-blue-600 text-white px-4 py-2 rounded-md">Publikálás</button>
    </form>
  )
}

A posztok listázása egy szerverkomponensben:

// app/dashboard/page.tsx
import { prisma } from "@/lib/prisma"
import Link from "next/link"

export default async function DashboardPage() {
  const posts = await prisma.post.findMany({
    include: { author: true },
    orderBy: { createdAt: "desc" }
  })
  
  return (
    <div>
      <h1>Saját bejegyzéseim</h1>
      <div className="grid gap-4">
        {posts.map(post => (
          <Link href={`/posts/${post.id}`} key={post.id} className="border p-4 rounded hover:shadow">
            <h2 className="text-xl font-bold">{post.title}</h2>
            <p>{post.content.slice(0, 100)}...</p>
            <small>Szerző: {post.author.name} – {new Date(post.createdAt).toLocaleDateString()}</small>
          </Link>
        ))}
      </div>
    </div>
  )
}

5. Deployment Vercel-re

A legjobb a Vercel, mert a Next.js készítői fejlesztik. Automatikusan felismeri a projektet, beállítja a build parancsokat, és kezeli a környezeti változókat.

  1. Pushold a kódot egy GitHub repóba.
  2. Menj a vercel.com oldalra, és importáld a repót.
  3. Állítsd be a környezeti változókat (DATABASE_URL, NEXTAUTH_SECRET, stb.) a Vercel irányítópultján.
  4. Kattints a Deploy gombra.

Ha PostgreSQL adatbázist használsz, a Vercel kínál beépített Neon vagy Supabase integrációt, de használhatsz máshol futó adatbázist is.

Best practice tippek a való világban

  • Használj típusbiztos API hívásokat – a Prisma típusait exportáld, hogy a frontend is lássa a modelleket.
  • Alkalmazz loading állapotokat – a loading.tsx fájlokkal azonnali visszajelzést adhatsz a felhasználónak.
  • Használd a unstable_noStore függvényt ha nem akarod cache-elni az adatokat (pl. személyes dashboard).
  • Vigyázz a szerver actionök validációjára – soha ne bízz a kliens oldali validációban, használd a Zod-ot.
Újságírói illusztráció

Ezzel a tudással már képes vagy egy teljes értékű full stack alkalmazás építésére. A Next.js 14 és a modern eszközök (Prisma, NextAuth, Tailwind) kombinációja hihetetlenül gyors fejlesztést tesz lehetővé. Ha bármi kérdésed van, írd meg a cikk alatti kommentekben!

Szabolcs Alex

Szabolcs Alex

Full Stack Developer & Tech Enthusiast

Szenvedélyes webfejlesztő, aki szeret megosztani tudását és tapasztalatait a modern webtechnológiákról. Ha kérdésed van, írj bátran!