- מפת מבנה מלאה של פרויקט Next.js עם הסבר לכל תיקייה וקובץ
- הבנה מלאה של file-based routing — כולל dynamic routes ו-route groups
- יכולת לקרוא package.json ולהבין מה כל dependency עושה
- cheat sheet: "רוצה X, תגיד ל-AI Y" — 10 תרחישים נפוצים
- הבנה של middleware, tsconfig ו-next.config ומתי לבקש מ-AI לשנות אותם
- ביטחון להנחות AI לשים כל קובץ חדש במקום הנכון בפרויקט
- למפות את מבנה התיקיות הסטנדרטי של פרויקט Next.js — app, components, lib, public, hooks
- להסביר מה file-based routing עושה ולדעת לבקש מ-AI ליצור דף חדש במקום הנכון
- לקרוא package.json ולהבין מה dependencies ו-scripts עושים
- להנחות AI להוסיף קומפוננטה חדשה למקום הנכון בפרויקט קיים
פרקים קודמים: פרק 1 (הווב ב-2026), פרק 2 (React), פרק 3 (Frameworks — במיוחד Next.js).
מה צריך: דפדפן עם גישה ל-AI (V0, Bolt, Lovable, Claude, או Cursor). לא צריך להתקין שום דבר — הפרק הזה קונספטואלי עם תרגולים מול AI.
זמן משוער: 50-65 דקות קריאה + תרגולים.
מאיפה באנו: בפרק 07 למדתם לבחור אייקונים (Lucide), פונטים (Heebo) ותמונות (Unsplash). עכשיו נלמד איפה כל אחד מהם יושב בתוך מבנה הפרויקט — הגדרות הפונט ב-layout.tsx, התמונות ב-public/, וספריית האייקונים כ-import מ-node_modules.
מה נעשה היום: נפרק פרויקט Next.js שלם — תיקייה אחרי תיקייה, קובץ אחרי קובץ. נבין מה routing, מה dynamic routes, ואיך להגיד ל-AI בדיוק איפה לשים כל דבר חדש.
לאן ממשיכים: בפרק 09 נלמד לפרוס את הפרויקט הזה לאוויר — Vercel, Netlify או Cloudflare Pages. מבנה הפרויקט שנלמד כאן קובע איך הפריסה עובדת.
| מונח (English) | תרגום | הסבר בשורה אחת |
|---|---|---|
| app directory | תיקיית app | התיקייה הראשית ב-Next.js שמגדירה את כל ה-routes של האתר |
| page.tsx | קובץ דף | קובץ שהופך תיקייה ל-route נגיש — בלעדיו התיקייה לא תהיה דף באתר |
| layout.tsx | קובץ פריסה | שכבת UI משותפת שעוטפת כל דף — header, footer, הגדרות גלובליות |
| loading.tsx | מסך טעינה | מסך טעינה שמופיע אוטומטית בזמן שהדף נטען |
| error.tsx | מסך שגיאה | מסך שגיאה שמופיע אוטומטית כשמשהו נשבר בדף |
| file-based routing | ניתוב מבוסס קבצים | שיטה שבה מבנה התיקיות קובע את ה-URLs — כל תיקייה עם page.tsx הופכת לנתיב |
| dynamic routes | נתיבים דינמיים | נתיבים עם פרמטרים משתנים — כמו דף מוצר שמשתנה לפי ID |
| route groups | קבוצות ניתוב | תיקיות בסוגריים () שמארגנות קוד בלי להשפיע על ה-URL |
| package.json | מניפסט הפרויקט | תעודת הזהות של הפרויקט — רשימת תלויות, סקריפטים והגדרות |
| dependencies | תלויות | חבילות שהפרויקט צריך כדי לרוץ — React, Next.js וכו׳ |
| devDependencies | תלויות פיתוח | חבילות שצריך רק בפיתוח — TypeScript, ESLint וכו׳ |
| node_modules | תיקיית חבילות | תיקייה ענקית שמכילה את כל החבילות המותקנות — לא נוגעים, לא מעלים ל-Git |
| tsconfig.json | הגדרות TypeScript | קובץ הגדרות TypeScript — כולל path aliases כמו @/ שמקצרים imports |
| middleware.ts | שכבת ביניים | קוד שרץ לפני כל בקשה — בדיקת הרשאות, הפניות, או שינוי headers |
| scripts | סקריפטים | פקודות מוכנות ב-package.json — dev להפעלה, build לבנייה, start לייצור |
מה AI מייצר כשאומרים "צור פרויקט Next.js"
כשאתם אומרים ל-V0, Bolt, Lovable, או כל AI אחר "צור לי פרויקט Next.js" — הוא לא יוצר קובץ אחד. הוא יוצר מבנה שלם של תיקיות וקבצים. בפרויקט טיפוסי יש 20-40 קבצים מהרגע הראשון, ואם ביקשתם גם shadcn/ui ו-Tailwind — אפילו יותר.
הנה מה שבדרך כלל נוצר:
my-project/
├── app/ # כל הדפים והניתוב
│ ├── layout.tsx # שלד האתר (header, footer, fonts)
│ ├── page.tsx # עמוד הבית (/)
│ ├── globals.css # סגנונות גלובליים
│ └── favicon.ico # האייקון בטאב של הדפדפן
├── components/ # קומפוננטות משותפות
│ └── ui/ # קומפוננטות shadcn/ui
├── lib/ # פונקציות עזר
│ └── utils.ts # utility functions
├── hooks/ # custom hooks
├── public/ # קבצים סטטיים (תמונות, לוגו)
├── package.json # תעודת זהות + תלויות
├── tsconfig.json # הגדרות TypeScript
├── next.config.ts # הגדרות Next.js
├── tailwind.config.ts # הגדרות Tailwind
├── postcss.config.js # הגדרות PostCSS
├── .gitignore # קבצים שלא עולים ל-Git
└── node_modules/ # כל החבילות (ענק!)
נראה מרשים? בואו נפרק את זה חלק אחרי חלק. אל תנסו לשנן — תבינו את הלוגיקה, ואז תדעו תמיד איפה לחפש.
הלוגיקה פשוטה: כל תיקייה יש לה תפקיד אחד ברור. app/ מנהלת את הדפים. components/ מחזיקה חלקים שחוזרים על עצמם. lib/ מחזיקה לוגיקה. public/ מחזיקה קבצים שהדפדפן צריך ישירות. וקבצי ההגדרות (package.json, tsconfig.json) אומרים לפרויקט איך להתנהג.
פתחו V0, Bolt או Lovable, בקשו "Create a Next.js landing page", והסתכלו על רשימת הקבצים שנוצרו. אל תקראו את הקוד — רק ספרו כמה תיקיות יש, וראו אם אתם מזהים את השמות מהרשימה למעלה.
חשוב להבין: AI שונים מייצרים מבנים קצת שונים. V0 נוטה ליצור מבנה נקי עם shadcn/ui מובנה. Bolt מוסיף לפעמים תיקיות נוספות. Lovable בונה מבנה משלו. אבל העקרונות זהים — אם אתם מבינים את המבנה הסטנדרטי, תבינו כל וריאציה.
הנה השוואה מהירה של מה כל כלי AI מייצר:
| כלי AI | Framework | ספריית UI | מבנה ברירת מחדל |
|---|---|---|---|
| V0 (by Vercel) | Next.js 15 | shadcn/ui + Tailwind | נקי ומסודר, app/ עם layout ו-page |
| Bolt | Next.js / Vite | shadcn/ui + Tailwind | דומה ל-V0, לפעמים מוסיף תיקיות נוספות |
| Lovable | Vite + React | shadcn/ui + Tailwind | מבנה קצת שונה — src/ במקום app/ |
| Claude Code | לפי בקשה | לפי בקשה | יוצר בדיוק מה שמבקשים |
| Cursor | לפי בקשה | לפי בקשה | עובד על פרויקט קיים — לא יוצר מאפס |
שימו לב ל-Lovable: הוא משתמש ב-Vite + React במקום Next.js, ולכן המבנה שלו קצת שונה — יש תיקיית src/ במקום app/, והניתוב נעשה עם ספרייה בשם react-router במקום file-based routing. כל מה שנלמד בפרק הזה רלוונטי בעיקר ל-Next.js — שהוא ברירת המחדל של V0, Bolt, ורוב כלי ה-AI.
הנקודה המרכזית: אתם לא צריכים לזכור כל קובץ. אתם צריכים לדעת 5 תיקיות ו-4 קבצים מיוחדים. זה הכל. את השאר תמיד אפשר לשאול את ה-AI.
חשבו על פרויקט שאתם רוצים לבנות (אתר פורטפוליו? חנות? בלוג?). כתבו רשימה של 3 דפים שהאתר צריך. בסוף הפרק תדעו בדיוק איפה כל דף יושב במבנה התיקיות.
תיקיית app/ — הלב של הפרויקט
תיקיית app/ היא המקום שבו כל הדפים של האתר שלכם חיים. זו ההמצאה המרכזית של App Router שלמדנו בפרק 03 — כל תיקייה בתוך app/ יכולה להפוך לדף באתר.
אבל לא כל קובץ בתוך app/ הוא דף. יש 4 קבצים מיוחדים ש-Next.js מזהה אוטומטית. כל אחד עושה משהו אחר:
| קובץ | מה הוא עושה | חובה? | דוגמה |
|---|---|---|---|
page.tsx |
הופך תיקייה לדף נגיש. זה התוכן שהמבקר רואה. | כן (לכל route) | app/about/page.tsx → /about |
layout.tsx |
עוטף את כל הדפים בשכבה משותפת — header, footer, font loading. לא נטען מחדש בניווט. | כן (ב-root) | Root layout: app/layout.tsx |
loading.tsx |
מסך טעינה שמופיע אוטומטית בזמן שהדף נטען. משתמש ב-React Suspense מאחורי הקלעים. | לא | ספינר או שלד בזמן טעינה |
error.tsx |
מסך שגיאה שמופיע כשמשהו נשבר. תופס שגיאות ומציג הודעה ידידותית במקום מסך לבן. | לא | "משהו השתבש, נסו שוב" |
נסביר את הלוגיקה עם משל: דמיינו בניין משרדים. layout.tsx הוא הלובי, המעלית, והמסדרונות — התשתית שכולם חולקים. page.tsx הוא החדר הספציפי שנכנסים אליו — התוכן המשתנה. loading.tsx הוא שלט "רגע, מכינים את החדר". error.tsx הוא שלט "החדר הזה סגור לתיקונים".
יש עוד שני קבצים מיוחדים שכדאי להכיר:
not-found.tsx— דף 404 שמופיע כשהמבקר מנסה לגשת לכתובת שלא קיימת. בלעדיו, Next.js מציג דף 404 גנרי ומשעמם. עם not-found.tsx מותאם — המבקר מקבל דף שנראה חלק מהאתר שלכם, עם ניווט חזרה.template.tsx— דומה ל-layout.tsx, אבל נוצר מחדש בכל ניווט. בעוד layout שומר state (לדוגמה: sidebar פתוחה), template מאפס הכל. זה שימושי כשרוצים אנימציות כניסה בכל מעבר דף.
הנה דוגמה למבנה app/ של אתר עם כמה דפים:
app/
├── layout.tsx # Root layout — עוטף הכל (html, body, fonts)
├── page.tsx # עמוד הבית (/)
├── loading.tsx # טעינה גלובלית
├── not-found.tsx # דף 404
├── globals.css # סגנונות גלובליים
├── about/
│ └── page.tsx # דף אודות (/about)
├── blog/
│ ├── page.tsx # רשימת פוסטים (/blog)
│ └── [slug]/
│ └── page.tsx # פוסט בודד (/blog/my-first-post)
└── contact/
└── page.tsx # דף יצירת קשר (/contact)
layout.tsx בתיקיית app/ הוא חובה. הוא מכיל את תגית <html> ו-<body> — בלעדיו אין HTML תקין. אם מחקתם אותו בטעות, האתר כולו יישבר. אם ה-AI שלכם מציע לערוך את layout.tsx — קראו מה הוא משנה לפני שאתם מאשרים. ואם משהו נשבר — בדקו שלא מחקתם layout.tsx.
מה Root Layout חייב לכלול:
// app/layout.tsx — המבנה הבסיסי
export default function RootLayout({ children }) {
return (
<html lang="he" dir="rtl">
<body>
{children} {/* כאן נכנס התוכן של כל דף */}
</body>
</html>
)
}
שימו לב ל-lang="he" dir="rtl" — זה מה שגורם לאתר להיות בעברית ומימין לשמאל. טיפ חשוב לשוק הישראלי: אם ה-AI לא הוסיף את זה, בקשו ממנו: "הגדר את ה-layout עם lang='he' dir='rtl' — האתר בעברית."
layout בפרויקט אמיתי כולל הרבה יותר:
// app/layout.tsx — גרסה מציאותית
import { Heebo } from 'next/font/google'
import './globals.css'
import { Header } from '@/components/layout/header'
import { Footer } from '@/components/layout/footer'
const heebo = Heebo({ subsets: ['hebrew'] })
export const metadata = {
title: 'האתר שלי',
description: 'אתר שנבנה עם Next.js',
}
export default function RootLayout({ children }) {
return (
<html lang="he" dir="rtl">
<body className={heebo.className}>
<Header />
{children}
<Footer />
</body>
</html>
)
}
שימו לב — ה-Header וה-Footer מיובאים מ-components/layout/. הפונט Heebo (שלמדנו בפרק 07) נטען עם next/font/google. ה-globals.css מכיל את ה-Tailwind directives. כל זה קורה פעם אחת ב-layout — וכל דף באתר מקבל את זה אוטומטית.
מה עוד שמים ב-Root Layout?
- Meta tags — כותרת האתר ותיאור (ל-SEO וביצת שיתוף)
- Google Analytics — סקריפט מעקב שצריך לרוץ בכל דף
- Theme Provider — ניהול dark/light mode גלובלי
- Toast/Notification Provider — הודעות צפות שמופיעות מכל דף
- טעינת פונט — הפונט נטען פעם אחת ב-layout, לא בכל דף
כל מה שצריך לרוץ בכל דף — הולך ל-Root Layout. כל מה שספציפי לדף אחד — הולך ל-page.tsx של אותו דף. זו הפרדת אחריות בסיסית — layout עוטף, page מציג תוכן.
שגיאה שה-AI עושה לפעמים: שם Google Analytics או שירותים חיצוניים בתוך page.tsx במקום ב-layout.tsx. התוצאה — הסקריפט נטען רק בעמוד הבית ולא בשאר הדפים. אם שירות צריך לרוץ בכל מקום — הוא חייב להיות ב-layout.tsx.
Layout מקונן (Nested Layout): אפשר ליצור layout נפרד לכל חלק באתר. לדוגמה, דפי הבלוג יכולים לקבל sidebar שלא מופיע בשאר האתר:
app/
├── layout.tsx # Root layout — Header + Footer לכולם
├── page.tsx # עמוד הבית
├── blog/
│ ├── layout.tsx # Blog layout — מוסיף Sidebar רק לבלוג
│ ├── page.tsx # רשימת פוסטים
│ └── [slug]/page.tsx # פוסט בודד
└── about/page.tsx # דף אודות (ללא sidebar)
כשמבקר נכנס ל-/blog, Next.js טוען שניהם: Root Layout (header+footer) ובתוכו Blog Layout (sidebar). כשנכנס ל-/about — רק Root Layout. זו עוצמה של layouts מקוננים — ה-AI יכול ליצור חוויות שונות לחלקים שונים באתר.
דוגמאות לשימוש ב-nested layouts בשוק הישראלי:
- אתר SaaS: Root Layout (header + footer כללי) → Dashboard Layout (sidebar עם ניווט פנימי) → Settings Layout (טאבים להגדרות)
- חנות אונליין: Root Layout (header עם עגלה) → Shop Layout (סרגל סינון בצד) → Product Layout (breadcrumbs + מוצרים קשורים)
- אתר תוכן / מגזין: Root Layout (ניווט ראשי) → Article Layout (sidebar עם תוכן עניינים) → Category Layout (פילטרים)
בקשו מ-AI: "הראה לי את layout.tsx של פרויקט Next.js בעברית." בדקו — האם יש lang="he" ו-dir="rtl"? האם יש טעינת פונטים? אלה שני הדברים הכי חשובים ב-layout.
SVG Diagram: מפת תיקיות של פרויקט Next.js
לפני שנצלול לכל תיקייה בנפרד, הנה מבט-על שמסכם את כל מבנה הפרויקט. שמרו את הדיאגרמה הזו — היא שווה זהב כשצריכים להיזכר איפה מה:
File-Based Routing — הנתיב בתיקייה = הנתיב ב-URL
זה אחד מהרעיונות הכי אלגנטיים ב-Next.js: מבנה התיקיות שלכם הוא ה-URL של האתר. לא צריך להגדיר routing בנפרד, לא צריך קובץ config, לא צריך לכתוב קוד ניתוב. התיקייה היא הנתיב.
הכלל פשוט:
| תיקייה + קובץ | URL באתר | הסבר |
|---|---|---|
app/page.tsx | / | עמוד הבית |
app/about/page.tsx | /about | דף אודות |
app/blog/page.tsx | /blog | רשימת הבלוג |
app/blog/first-post/page.tsx | /blog/first-post | פוסט ספציפי |
app/products/shoes/page.tsx | /products/shoes | קטגוריית נעליים |
שימו לב לנקודה קריטית: רק תיקייה שיש בה page.tsx הופכת ל-route. אם יש תיקייה בלי page.tsx — היא לא דף באתר. זה אומר שאפשר ליצור תיקיות לארגון בלי שהן יהפכו לדפים.
מה קורה כשמבקר גולש לדף?
- Next.js מקבל את ה-URL (למשל
/about) - מחפש תיקייה מתאימה ב-app/ (למצא
app/about/) - בודק שיש
page.tsxבתיקייה - טוען את
layout.tsxשל ההורה (Root Layout) - מרנדר את ה-layout עם ה-page בתוכו
- אם יש
loading.tsx— מציג אותו בזמן הטעינה - אם יש שגיאה ו-
error.tsxקיים — מציג את מסך השגיאה
כל הזרימה הזו קורית אוטומטית. אתם לא צריכים לכתוב קוד routing — רק ליצור תיקיות ולשים בהן את הקבצים הנכונים. זה file-based routing.
למה זה חשוב ל-Vibe Coders? כי עכשיו כשאתם רוצים להוסיף דף חדש, אתם יודעים בדיוק מה לבקש מ-AI:
צור דף "שירותים" באתר Next.js שלי.
הקובץ צריך להיות ב-app/services/page.tsx.
השתמש ב-layout.tsx הקיים.
הדף צריך להיות Server Component.
בלי להבין file-based routing, הייתם אומרים "תוסיף דף שירותים" — וה-AI היה מחליט לבד איפה לשים אותו, ואולי בוחר מקום שלא מתאים למבנה הקיים.
דוגמה מהשוק הישראלי: סטארט-אפ ישראלי שבונה אתר SaaS עם AI צריך בדרך כלל את הדפים האלה:
app/
├── page.tsx # Landing page (/)
├── pricing/page.tsx # דף תמחור (/pricing)
├── features/page.tsx # יכולות המוצר (/features)
├── blog/
│ ├── page.tsx # רשימת מאמרים (/blog)
│ └── [slug]/page.tsx # מאמר בודד (/blog/ai-trends-2026)
├── login/page.tsx # כניסה (/login)
├── signup/page.tsx # הרשמה (/signup)
├── dashboard/
│ ├── page.tsx # דשבורד (/dashboard)
│ ├── settings/page.tsx # הגדרות (/dashboard/settings)
│ └── projects/
│ ├── page.tsx # רשימת פרויקטים (/dashboard/projects)
│ └── [id]/page.tsx # פרויקט בודד (/dashboard/projects/42)
└── api/
├── auth/route.ts # API לאימות
└── contact/route.ts # API ליצירת קשר
שימו לב איך המבנה הפיזי של התיקיות משקף את המבנה הלוגי של האתר. אין קסמים, אין config files מסובכים — רק תיקיות וקבצים. כל מתכנת (או AI) שפותח את הפרויקט מבין מיד מה יש באתר.
טיפ מעשי: כשמתחילים פרויקט חדש, בקשו מה-AI ליצור את מבנה התיקיות לפני שמתחילים לכתוב קוד. קל יותר לתכנן מבנה ריק מאשר לסדר מבנה שכבר מלא. כתבו: "צור את מבנה התיקיות לפרויקט [תאור הפרויקט] — אל תכתוב קוד עדיין, רק את התיקיות והקבצים הריקים."
Next.js תומך בשתי שיטות routing: pages/ (הישנה) ו-app/ (החדשה). ערבוב בין השתיים גורם לבאגים מבלבלים ששניהם עובדים "בערך" אבל קונפליקטים ביניהם. בכל פרויקט חדש, ציינו ל-AI: "השתמש רק ב-App Router עם תיקיית app/ — אל תיצור תיקיית pages/."
בקשו מ-AI: "צור דף about בפרויקט Next.js." בדקו — האם הוא שם את הקובץ ב-app/about/page.tsx? אם כן — הוא עשה את זה נכון. אם הוא שם אותו ב-pages/about.tsx — הוא השתמש בגישה הישנה.
Dynamic Routes — דפים שמשתנים לפי פרמטר
יש לכם חנות עם 500 מוצרים. אתם לא הולכים ליצור 500 תיקיות. במקום זה, Next.js נותן לכם dynamic routes — תיקיות עם סוגריים מרובעים שאומרות "כאן יהיה פרמטר שמשתנה".
הנה שלושה סוגי סוגריים ומה כל אחד עושה:
| תחביר | דוגמה | URL שתואם | מתי להשתמש |
|---|---|---|---|
[id] |
app/products/[id]/page.tsx |
/products/123, /products/abc |
פרמטר אחד — מוצר, פוסט, משתמש |
[...slug] |
app/docs/[...slug]/page.tsx |
/docs/a, /docs/a/b/c |
נתיב עם עומק משתנה — דוקומנטציה |
[[...slug]] |
app/shop/[[...slug]]/page.tsx |
/shop, /shop/men/shoes |
כמו catch-all אבל גם בלי פרמטר |
הכי נפוץ: [id] — פרמטר אחד. 90% מהמקרים זה מה שצריכים. דף מוצר, פוסט בבלוג, פרופיל משתמש — כולם [id].
Route Groups — ארגון בלי השפעה על URL
לפעמים רוצים לארגן קבצים בתיקיות בלי שהתיקייה תופיע ב-URL. לזה יש סוגריים עגולים:
app/
├── (marketing)/ # לא מופיע ב-URL!
│ ├── about/page.tsx # /about (לא /marketing/about)
│ └── pricing/page.tsx # /pricing
├── (dashboard)/ # לא מופיע ב-URL!
│ ├── settings/page.tsx # /settings
│ └── profile/page.tsx # /profile
└── page.tsx # /
Route groups מאפשרים לכם לארגן את הקוד לפי לוגיקה עסקית (שיווק, דשבורד, ניהול) בלי שזה משפיע על מה שהמבקר רואה ב-URL. טיפ: כל route group יכול גם לקבל layout.tsx משלו — כך שלדפי השיווק יש עיצוב אחד ולדשבורד עיצוב אחר.
איך dynamic route עובד בפועל? כשיוצרים app/products/[id]/page.tsx, הקובץ מקבל את הפרמטר כ-prop:
// app/products/[id]/page.tsx
export default function ProductPage({ params }) {
// אם המבקר גולש ל-/products/42
// אז params.id = "42"
return <h1>מוצר מספר {params.id}</h1>
}
לא צריך לכתוב את זה — ה-AI כותב. אבל כדאי להבין שה-[id] בשם התיקייה הופך ל-params.id בקוד. אם שניתם את השם ל-[slug] — הפרמטר יהיה params.slug. השם בסוגריים המרובעים קובע את שם המשתנה.
דוגמה מתקדמת — Nested Dynamic Routes:
app/shop/[category]/[productId]/page.tsx
# URL: /shop/electronics/iphone-15
# params.category = "electronics"
# params.productId = "iphone-15"
זו דרך נפוצה לבנות ניווט בחנות — קטגוריה ואז מוצר. כל שכבה של סוגריים מרובעים מוסיפה פרמטר.
מתי לבחור Catch-All? דמיינו אתר תיעוד (documentation) — כמו docs.mysite.com. הנתיבים שם עמוקים: /docs/getting-started, /docs/api/auth/tokens, /docs/guides/deployment/vercel. כל הנתיבים האלה צריכים את אותו layout ואותו עיצוב, אבל העומק משתנה. Catch-all route ([...slug]) פותר את זה — קובץ אחד שתופס כל עומק URL.
Catch-All vs Optional Catch-All:
[...slug]— תופס/docs/a,/docs/a/b,/docs/a/b/c— אבל לא תופס/docs(בלי פרמטר)[[...slug]]— תופס גם/docs(בלי פרמטר) + כל העומקים. השתמשו בזה כשרוצים שגם הנתיב הבסיסי יעבוד.
חשבו על אתר חנות. כתבו 3 נתיבים שצריכים להיות דינמיים (לדוגמה: דף מוצר, דף קטגוריה, דף סינון). עכשיו כתבו את מבנה התיקיות — איך כל אחד ייראה ב-app/?
| מצב | סוג Route | מה לכתוב ל-AI |
|---|---|---|
| אותו layout, מידע שונה (מוצר, פוסט) | [id] | "צור דף מוצר דינמי ב-app/products/[id]/page.tsx" |
| עומק URL משתנה (docs, wiki) | [...slug] | "צור routing עם catch-all ב-app/docs/[...slug]/page.tsx" |
| אותו דבר + גם עמוד ראשי | [[...slug]] | "צור optional catch-all — גם /shop וגם /shop/category" |
| ארגון פנימי בלי השפעה על URL | (group) | "צור route group בשם (marketing) לדפים השיווקיים" |
SVG Diagram: File-Based Routing — מתיקייה ל-URL
הנה מיפוי ויזואלי שמראה בדיוק איך תיקיות הופכות ל-URLs:
תיקיית components/ — הקומפוננטות המשותפות
בפרק 02 למדנו ש-React עובד עם קומפוננטות — חלקים קטנים ושימושיים חוזר שמרכיבים את הדף. כל הקומפוננטות ה"גלובליות" — כאלה שמשמשות יותר מדף אחד — חיות בתיקיית components/.
המבנה הנפוץ:
components/
├── ui/ # קומפוננטות shadcn/ui (Button, Card, Dialog...)
│ ├── button.tsx
│ ├── card.tsx
│ ├── dialog.tsx
│ └── input.tsx
├── layout/ # חלקים מבניים (Header, Footer, Sidebar)
│ ├── header.tsx
│ ├── footer.tsx
│ └── sidebar.tsx
├── forms/ # טפסים (ContactForm, SearchBar)
│ ├── contact-form.tsx
│ └── search-bar.tsx
└── shared/ # קומפוננטות משותפות אחרות
├── logo.tsx
└── theme-toggle.tsx
למה חשוב לדעת את זה? כשאתם אומרים ל-AI "צור כפתור" בלי לציין איפה לשים אותו — הוא עלול לכתוב את הכפתור ישירות בתוך הדף. זה עובד, אבל אם תרצו לשנות את הכפתור בכל הדפים — תצטרכו לשנות בכל מקום בנפרד. זו הבעיה של קוד כפול (code duplication).
הפתרון: קומפוננטה נפרדת בתיקיית components/. ככה, כפתור אחד מוגדר פעם אחת — וכל דף משתמש בו. שינוי בקובץ אחד = שינוי בכל האתר. זו בדיוק הסיבה שבפרק 02 למדנו לחשוב בקומפוננטות.
הבדל חשוב — components/ui/ vs components/layout/:
components/ui/— קומפוננטות קטנות ואטומיות: כפתור, קלט, כרטיס, דיאלוג. בדרך כלל אלה קומפוננטות shadcn/ui שהתקנתם בפרק 05.components/layout/— חלקים מבניים גדולים: Header (עם ניווט ולוגו), Footer (עם לינקים), Sidebar (עם תפריט). אלה מיובאים ל-layout.tsx.components/forms/— טפסים שלמים: ContactForm, LoginForm, SearchBar. טופס = שילוב של כמה קומפוננטות ui/ יחד.
הדרך הנכונה לבקש מ-AI קומפוננטה חדשה:
צור קומפוננטת testimonial card.
שים אותה ב-components/ui/testimonial-card.tsx.
השתמש ב-shadcn Card כבסיס.
תייבא אותה מ-app/page.tsx.
AI נוטה ליצור קבצים ארוכים מאוד — 500 שורות ויותר עם כל הקומפוננטות בקובץ אחד. זה עובד אבל בלתי אפשרי לתחזוקה. אחרי שה-AI יוצר קובץ גדול, בקשו ממנו: "פצל את הקובץ הזה לקומפוננטות נפרדות בתיקיית components/". הוא יעשה את זה בכיף — פשוט צריך לבקש.
בקשו מ-AI: "הראה לי איזה קומפוננטות יש בתיקיית components/ של פרויקט Next.js טיפוסי עם shadcn/ui." השוו לרשימה למעלה — מה חופף? מה שונה?
תיקיות lib/, hooks/ ו-public/ — כל אחת עם תפקיד
שלוש תיקיות נוספות שתראו בכל פרויקט, וכל אחת עם תפקיד ברור:
lib/ — הלוגיקה מאחורי הקלעים
תיקיית lib/ (קיצור של library) מכילה פונקציות עזר שלא קשורות ל-UI. אם components/ היא "מה שרואים", אז lib/ היא "מה שעובד מאחורי הקלעים".
lib/
├── utils.ts # פונקציות עזר (cn() ל-className merge)
├── api.ts # פונקציות גישה ל-API
├── constants.ts # קבועים (צבעים, URLs, הגדרות)
├── validations.ts # בדיקות תקינות לטפסים
└── supabase.ts # חיבור ל-Supabase (אם משתמשים)
הקובץ הכי נפוץ כאן הוא utils.ts. כש-shadcn/ui מותקנת, הוא מכיל פונקציה בשם cn() שמאפשרת לשלב classes של Tailwind בצורה נוחה — שלמדנו בפרק 04. אל תמחקו את הקובץ הזה — הרבה קומפוננטות shadcn תלויות בו ובלעדיו הן יישברו.
מה עוד נמצא ב-lib/?
api.ts— פונקציות שמתקשרות עם שרתים חיצוניים (fetch data, שליחת טפסים)constants.ts— ערכים קבועים שחוזרים על עצמם (URL של ה-API, שמות חברה, צבעי מותג)validations.ts— בדיקות תקינות לטפסים (האם email תקין? האם הסיסמה חזקה מספיק?)supabase.tsאוfirebase.ts— חיבור למסד נתונים (אם הפרויקט דורש backend)
כלל אצבע: אם זה קוד שלא קשור ישירות ל-UI (לא מרנדר שום דבר למסך) — הוא הולך ל-lib/. אם זה קוד שכן מרנדר UI (מחזיר JSX) — הוא הולך ל-components/. ואם זה קוד שמשתמש ב-React hooks — הוא הולך ל-hooks/.
hooks/ — לוגיקה שמתחברת ל-React
תיקיית hooks/ מכילה custom hooks — פונקציות מיוחדות שמשתמשות ביכולות של React (כמו useState ו-useEffect שלמדנו בפרק 02). הן מאפשרות שימוש חוזר בלוגיקה.
hooks/
├── use-mobile.ts # זיהוי אם המבקר בנייד
├── use-scroll.ts # מעקב אחרי גלילה
├── use-theme.ts # ניהול dark/light mode
└── use-debounce.ts # השהיית קריאות API בחיפוש
כלל אצבע: אם שם הקובץ מתחיל ב-use- — זה hook. אם ה-AI יצר hook, הוא צריך להיות בתיקיית hooks/. אם הוא שם אותו במקום אחר — בקשו ממנו להעביר.
מה ההבדל בין hook ל-utility function? פונקציות ב-lib/ הן "טהורות" — הן מקבלות מידע ומחזירות תוצאה, בלי קשר ל-React. hooks ב-hooks/ משתמשות ביכולות ספציפיות של React (כמו useState, useEffect, useRef שלמדנו בפרק 02). אם אתם מזהים use בתחילת השם — זה hook, ומקומו ב-hooks/.
דוגמאות מעשיות:
formatDate(date)— פונקציית עזר שמפרמטת תאריך. הולכת ל-lib/utils.ts.useMobile()— hook שמזהה אם המשתמש בנייד (משתמש ב-useState). הולך ל-hooks/use-mobile.ts.fetchProducts()— פונקציה שמביאה מוצרים מ-API. הולכת ל-lib/api.ts.useCart()— hook שמנהל מצב עגלת קניות (useState + useEffect). הולך ל-hooks/use-cart.ts.
public/ — קבצים שהדפדפן רואה ישירות
תיקיית public/ מכילה קבצים סטטיים שהדפדפן ניגש אליהם ישירות — בלי שום עיבוד. כל קובץ ב-public/ זמין דרך ה-URL של האתר.
public/
├── images/ # תמונות (מ-Unsplash, לוגואים)
│ ├── hero.webp
│ └── logo.svg
├── favicon.ico # האייקון בטאב הדפדפן
├── robots.txt # הוראות ל-Google (SEO)
├── sitemap.xml # מפת האתר (SEO)
└── og-image.png # תמונה לשיתוף ברשתות חברתיות
הכלל: public/images/hero.webp → ניגש דרך mysite.com/images/hero.webp. פשוט. התיקייה public/ "נעלמת" מה-URL — רק מה שבתוכה נשאר.
זוכרים את פרק 07? התמונות מ-Unsplash שלמדתם לבחור — הן הולכות ל-public/images/. הלוגו שלכם — public/logo.svg. ה-favicon — public/favicon.ico. עכשיו אתם יודעים בדיוק איפה הם חיים.
מה ההבדל בין תמונה ב-public/ לבין תמונה שמיובאת בקוד?
| שיטה | איך משתמשים | מתי לבחור |
|---|---|---|
public/ |
<img src="/images/hero.webp" /> |
תמונות גדולות שלא משתנות, favicon, og-image |
| import בקוד | import logo from './logo.svg' |
תמונות קטנות שמשתנות לפי theme, אייקונים מיוחדים |
| next/image | <Image src="/images/hero.webp" /> |
תמונות שצריכות אופטימיזציה אוטומטית (שלמדנו בפרק 07) |
כלל אצבע: אם אתם בונים עם Next.js — השתמשו ב-next/image כמעט תמיד. שימו את התמונה ב-public/images/ ותייחסו אליה עם src="/images/hero.webp". Next.js ידאג לאופטימיזציה אוטומטית.
| סוג הקובץ | תיקייה | דוגמה | Prompt ל-AI |
|---|---|---|---|
| דף באתר | app/[route]/ | דף אודות | "צור דף ב-app/about/page.tsx" |
| קומפוננטת UI | components/ui/ | כפתור, כרטיס | "צור קומפוננטה ב-components/ui/card.tsx" |
| חלק מבני (header) | components/layout/ | Header, Footer | "צור header ב-components/layout/header.tsx" |
| פונקציית עזר | lib/ | חיבור API | "הוסף API client ב-lib/api.ts" |
| Custom hook | hooks/ | זיהוי נייד | "צור hook ב-hooks/use-mobile.ts" |
| תמונה / לוגו | public/images/ | hero image | "שים את התמונה ב-public/images/hero.webp" |
| API endpoint | app/api/ | form submit | "צור API route ב-app/api/contact/route.ts" |
פתחו כל אתר, לחצו F12, וב-Network tab (סננו ל-Img) חפשו קבצי תמונות. שימו לב לנתיבים — אלה קבצים סטטיים שחיים בתיקיית public/ (או equivalent).
package.json — תעודת הזהות של הפרויקט
כל פרויקט Node.js (כולל Next.js) מתחיל עם קובץ אחד: package.json. הוא "תעודת הזהות" של הפרויקט — מי הפרויקט, מה הוא צריך כדי לעבוד, ואיך מפעילים אותו.
הנה package.json טיפוסי של פרויקט Next.js עם shadcn/ui:
{
"name": "my-portfolio",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"next": "^15.1.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"lucide-react": "^0.460.0",
"@radix-ui/react-dialog": "^1.1.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"tailwind-merge": "^2.6.0"
},
"devDependencies": {
"typescript": "^5.7.0",
"@types/react": "^19.0.0",
"@types/node": "^22.0.0",
"tailwindcss": "^4.0.0",
"eslint": "^9.0.0",
"eslint-config-next": "^15.1.0"
}
}
בואו נפרק את זה חלק אחרי חלק:
scripts — הפקודות שמפעילות את הפרויקט
| פקודה | מה היא עושה | מתי משתמשים |
|---|---|---|
npm run dev | מפעילה שרת פיתוח מקומי (localhost:3000) | בזמן שעובדים — רואים שינויים בזמן אמת |
npm run build | בונה גרסת production מותאמת וקטנה | לפני העלאה לאוויר |
npm run start | מפעילה את גרסת ה-production | בשרת הייצור |
npm run lint | בודקת שגיאות וסטנדרטים בקוד | לפני commit / deploy |
הפקודה שתשתמשו בה הכי הרבה: npm run dev. היא מפעילה את האתר על המחשב שלכם ב-localhost:3000 (כתובת מקומית שרק אתם רואים). כל שינוי בקוד מתעדכן אוטומטית — זה נקרא Hot Module Replacement (HMR), ובגרסה החדשה של Next.js הוא משתמש ב-Turbopack שהוא מהיר במיוחד.
מה ה-^ (caret) אומר ליד גרסה? כש-package.json מציין "next": "^15.1.0", ה-^ אומר "גרסה 15.1.0 או גבוהה יותר, אבל בתוך 15.x.x בלבד". זה מאפשר עדכוני באגים אוטומטיים בלי לשבור דברים. לא צריך לזכור את זה — אבל כשתראו ^ לא תיבהלו.
dependencies — חבילות שהאתר צריך כדי לעבוד
אלה החבילות שנכנסות ל-production — כלומר, המשתמש הסופי צריך אותן. כמה דוגמאות מהרשימה למעלה:
| חבילה | מה היא עושה | למדנו בפרק |
|---|---|---|
next | ה-framework עצמו — כל ה-routing, SSR, ובנייה | פרק 03 |
react | ספריית ה-UI — קומפוננטות, state, hooks | פרק 02 |
lucide-react | ספריית אייקונים (Lucide) | פרק 07 |
@radix-ui/react-dialog | קומפוננטת Dialog מ-Radix (ה-primitives של shadcn) | פרק 05 |
class-variance-authority | ניהול וריאציות של קומפוננטות (primary/secondary button) | - |
tailwind-merge | מיזוג classes של Tailwind בלי קונפליקטים | פרק 04 |
devDependencies — חבילות שצריך רק בפיתוח
אלה חבילות שעוזרות לכם בזמן העבודה, אבל לא נכנסות לאתר הסופי. למשל TypeScript — המהדר (compiler) רץ בזמן הפיתוח, אבל הדפדפן מקבל JavaScript רגיל.
ההבדל שחשוב ל-Vibe Coders: אתם לא צריכים לנהל את ה-dependencies ידנית. כש-AI מוסיף חבילה — הוא מריץ npm install package-name והיא מתווספת אוטומטית ל-package.json. אבל כדאי לדעת לקרוא את הרשימה כדי להבין מה בפרויקט.
מה קורה כשמריצים npm install?
- npm קורא את package.json
- מוריד את כל ה-dependencies ו-devDependencies
- שם את הכל ב-node_modules/
- יוצר או מעדכן את package-lock.json (שנועל גרסאות)
למה לפעמים npm install נכשל? שלוש סיבות נפוצות:
| שגיאה | מה קרה | מה לעשות |
|---|---|---|
| ERESOLVE | קונפליקט בין גרסאות חבילות | בקשו מ-AI: "תקן את קונפליקט הגרסאות ב-package.json" |
| EACCES | אין הרשאות כתיבה | אל תריצו sudo! בקשו מ-AI לפתור הרשאות npm |
| ENOENT | חסר package.json | וודאו שאתם בתיקייה הנכונה |
טיפ מנוסה: אם npm install נתקע או נכשל — הפתרון הכי נפוץ הוא למחוק ולהתקין מחדש:
rm -rf node_modules package-lock.json
npm install
זה פותר 80% מבעיות ההתקנה. שמרו את הפקודה הזו — תצטרכו אותה.
בקשו מ-AI: "הראה לי את ה-package.json של פרויקט Next.js עם shadcn/ui ו-Lucide icons." ספרו — כמה dependencies יש? כמה devDependencies? נסו לזהות 3 חבילות שלמדתם עליהן בפרקים קודמים.
node_modules — הענק השקט
בפרק 01 הזכרנו ש-npm install לוקח זמן. עכשיו נבין למה: הפקודה הזו מורידה את כל החבילות שרשומות ב-package.json (ואת כל החבילות שהן צריכות, ואת כל החבילות שאלה צריכות...) ושמה אותן בתיקייה אחת ענקית: node_modules/.
מספרים שצריך לדעת:
- גודל טיפוסי: 200-500 MB לפרויקט Next.js רגיל
- מספר קבצים: עשרות אלפים (לפעמים מעל 100,000)
- אף פעם לא עולה ל-Git: תמיד מופיע ב-
.gitignore - אפשר למחוק ולשחזר:
rm -rf node_modules && npm install
שלושה כללים בלבד לגבי node_modules:
- לא נכנסים. אף פעם אל תערכו קבצים בתוך node_modules.
- לא מעלים. לעולם לא ל-Git, לעולם לא לשום מקום.
- אפשר למחוק. אם משהו מתנהג מוזר — מחקו את node_modules והריצו npm install מחדש. זה פותר 80% מהבעיות.
מה זה package-lock.json? קובץ שנוצר אוטומטית ונועל את הגרסאות המדויקות של כל חבילה. בניגוד ל-node_modules — את הקובץ הזה כן מעלים ל-Git. הוא מבטיח שכשמישהו אחר (או שרת build) ירוץ npm install — הוא יקבל בדיוק את אותן גרסאות.
סיכום: מה עולה ל-Git ומה לא?
| קובץ/תיקייה | עולה ל-Git? | למה? |
|---|---|---|
| package.json | כן ✅ | מגדיר את התלויות |
| package-lock.json | כן ✅ | נועל גרסאות מדויקות |
| node_modules/ | לא ❌ | ענק, אפשר לשחזר עם npm install |
| .env.local | לא ❌ | מכיל secrets (API keys) |
| .next/ | לא ❌ | תיקיית build — נוצרת מחדש |
| כל השאר | כן ✅ | קוד, הגדרות, תמונות |
כל אלה כבר מוגדרים ב-.gitignore שה-AI יוצר אוטומטית. אבל כדאי להבין למה כל שורה שם — כדי שלא תמחקו שורות חשובות בטעות כשעורכים את הקובץ. טיפ: אם ביצעתם push ל-GitHub ואחרי זה הבנתם ש-secrets נכנסו — לא מספיק למחוק אותם. הם נשארים בהיסטוריית Git. תצטרכו לבטל את ה-key ולייצר חדש. מניעה עדיפה על ריפוי.
קורה בעיקר ל-Vibe Coders שעובדים בלי template מוכן או שמחקו את .gitignore בטעות ("זה סתם קובץ ריק לא?"). אתם מריצים git add . → git commit -m "first commit" → git push, ופתאום ה-push תקוע לדקות ארוכות או נכשל עם השגיאה "file too large" (GitHub חוסם קבצים מעל 100MB). הבעיה: 200-500MB של node_modules עם עשרות אלפי קבצים נכנסו ל-Git. התוצאות: (1) הכל איטי — כל git clone מוריד חצי ג'יגה, (2) GitHub חוסם או מאט, (3) אם יש secrets בחבילות (נדיר אבל קורה) — הם חשופים לעד, (4) היסטוריית Git מזוהמת גם אם תמחקו את node_modules בcommit הבא, הקבצים נשארים ב-history לנצח (או עד git filter-branch).
הפתרון: לפני ה-commit הראשון, וודאו שיש .gitignore ושיש בו לפחות: node_modules/, .next/, .env*.local, dist/, build/. כלי AI כמו V0, Lovable ו-create-next-app יוצרים .gitignore נכון אוטומטית — אל תמחקו אותו. אם כבר עשיתם commit בטעות: הרצו git rm -r --cached node_modules, הוסיפו node_modules/ ל-.gitignore, וcommit מחדש. לנקות את ה-history לגמרי — git filter-repo או BFG Repo-Cleaner (אבל עדיף פשוט לפתוח repo חדש אם הפרויקט צעיר).
הסיטואציה: יש לכם פרויקט ישן שנוצר לפני שנתיים (Next.js 12/13) עם pages/ router. עכשיו אתם מבקשים מ-AI "add a /dashboard page" — ו-AI מייצר לכם app/dashboard/page.tsx, כי זה ברירת המחדל ב-Next.js 14+. Next.js לא זורק שגיאה — הוא תומך בשני ה-routers במקביל, וזה בדיוק הבעיה. מה קורה: (1) app/ מנצח על pages/ אם יש התנגשות נתיבים, אבל לא תמיד באופן עקבי. (2) קונבנציות ההביאת נתונים שונות לגמרי — ב-pages/ זה getServerSideProps/getStaticProps, ב-app/ זה async components. AI מערבב ביניהם ומייצר קוד שבור. (3) Middleware מתנהג אחרת בכל אחד. (4) Global CSS ו-layouts סותרים — יש _app.tsx מ-pages וגם layout.tsx מ-app, ולא ברור איזה מכתיב. (5) bundle size תופח — Next.js טוען runtime של שניהם.
הפתרון: בחרו אחד והתחייבו. לפרויקט חדש — תמיד app/ (זו ברירת המחדל של Next.js 14+ ו-V0). לפרויקט ישן שעובד — אל תתחילו להוסיף app/ עד שתהיו מוכנים להגר הכל. לפני כל פרומפט ציינו: "This project uses App Router only (app/ directory). Do not create any files in pages/. Use async Server Components for data fetching." אם הורשתם פרויקט עם שניהם — תוכנית מיגרציה: מגרים דף-דף מ-pages/ ל-app/, מוחקים את pages/ רק כשכולו עבר ונבדק.
בקשו מ-AI: "הראה לי קובץ .gitignore טיפוסי של פרויקט Next.js." ראו אילו קבצים ותיקיות הוא מתעלם מהם — וודאו ש-node_modules ו-.env.local שם.
tsconfig.json ו-next.config — הגדרות שאפשר לשנות
שני קבצי הגדרות שתראו בשורש כל פרויקט. לא צריך להבין כל שורה — צריך לדעת מה אפשר לבקש מ-AI לשנות בהם.
tsconfig.json — הגדרות TypeScript
TypeScript היא שפת תכנות שמרחיבה את JavaScript עם "סוגי נתונים" (types). בעולם של AI, כמעט כל פרויקט נוצר עם TypeScript — ולכן אתם רואים קבצים עם סיומת .tsx במקום .jsx.
הדבר הכי שימושי ב-tsconfig.json ל-Vibe Coders הוא path aliases:
// tsconfig.json (חלק רלוונטי)
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"] // או "./*" — תלוי בפרויקט
}
}
}
מה זה נותן? במקום לכתוב imports ארוכים ומבלבלים:
// בלי path alias — ארוך ומבלבל
import { Button } from '../../../components/ui/button'
// עם path alias — קצר וברור
import { Button } from '@/components/ui/button'
ה-@/ מחליף את כל הנתיב היחסי. כשאתם רואים @/ ב-import — זה אומר "מתחילים מ-root של הפרויקט". כש-AI כותב imports — הוא בדרך כלל משתמש ב-@/. עכשיו אתם מבינים מאיפה זה בא.
למה path aliases חשובים? בפרויקט גדול, imports יחסיים הופכים לסיוט:
// בלי alias — כשהקובץ עמוק
import { Button } from '../../../../components/ui/button'
import { formatDate } from '../../../../lib/utils'
import { useScroll } from '../../../../hooks/use-scroll'
// עם @/ alias — תמיד אותו דבר, לא משנה כמה עמוק
import { Button } from '@/components/ui/button'
import { formatDate } from '@/lib/utils'
import { useScroll } from '@/hooks/use-scroll'
אם ה-AI שלכם כותב imports עם ../../../ ארוכים — בקשו ממנו: "השתמש ב-@/ path alias לכל ה-imports."
next.config.ts — הגדרות Next.js
קובץ שמאפשר לשנות את ההתנהגות של Next.js. הדברים הכי נפוצים שמבקשים מ-AI לשנות כאן:
| הגדרה | מה היא עושה | Prompt ל-AI |
|---|---|---|
images.remotePatterns | מאפשרת טעינת תמונות מדומיינים חיצוניים | "הוסף ל-next.config תמיכה בתמונות מ-unsplash.com" |
redirects | הפניות מ-URL ישן לחדש | "הוסף redirect מ-/old-page ל-/new-page" |
env | משתני סביבה שזמינים בקוד | "הגדר את API_URL כ-environment variable" |
על Environment Variables: משתני סביבה (Environment Variables) הם ערכים שמשתנים בין סביבות — למשל, API key שונה ל-development ו-production. הם חיים בקבצי .env:
# .env.local — קובץ שנשאר רק במחשב שלכם
DATABASE_URL="postgresql://localhost:5432/mydb"
NEXT_PUBLIC_API_URL="https://api.mysite.com"
SECRET_API_KEY="sk-1234567890"
הכלל: משתנים שמתחילים ב-NEXT_PUBLIC_ זמינים גם בדפדפן (בקוד הצד-לקוח). משתנים בלי הקידומת הזו זמינים רק בשרת — מה שהופך אותם בטוחים לסודות כמו API keys.
אל תשימו secrets בקוד! תמיד ב-.env.local שלא עולה ל-Git. ה-AI לפעמים שם API keys ישירות בקוד — זו טעות אבטחה חמורה. אם הפרויקט עולה ל-GitHub — כל העולם יראה את ה-key שלכם. בקשו מה-AI: "העבר את ה-API key ל-environment variable ב-.env.local. אל תשים secrets ישירות בקוד."
דוגמה לקובצי .env מרובים:
.env # ברירת מחדל (עולה ל-Git — רק ערכים לא סודיים)
.env.local # מקומי (לא עולה ל-Git — secrets פה)
.env.development # סביבת פיתוח
.env.production # סביבת ייצור
.env.local תמיד דורס (overrides) את .env. לכן secrets הולכים ל-.env.local והגדרות כלליות (כמו שם האתר) הולכות ל-.env.
בקשו מ-AI: "מה @/ אומר ב-import statements ב-Next.js?" — התשובה קשורה ל-tsconfig.json שדיברנו עליו. אם התשובה מזכירה "path alias" — אתם בכיוון.
Middleware — הסינון לפני שהדף נטען
דמיינו מאבטח בכניסה לבניין. הוא בודק כל אחד לפני שהם נכנסים — יש לך כרטיס? מותר לך להיכנס לקומה הזו? Middleware ב-Next.js עושה בדיוק את זה — הוא קוד שרץ לפני כל בקשה לאתר שלכם.
איפה הוא חי: בניגוד לכל הקבצים האחרים, middleware.ts חי בשורש הפרויקט, לא בתוך app/:
my-project/
├── middleware.ts # <-- כאן! בשורש, לא בתוך app/
├── app/
├── components/
└── ...
מה אפשר לעשות עם middleware?
| תרחיש | מה middleware עושה | דוגמה |
|---|---|---|
| אימות (Authentication) | בודק אם המשתמש מחובר | מפנה לדף login אם לא מחובר |
| הפניות (Redirects) | מנתב מ-URL ישן לחדש | /blog → /articles |
| שפה (i18n) | מזהה שפת המבקר ומפנה | מבקר ישראלי → /he/... |
| A/B Testing | מפנה מבקרים לגרסאות שונות | 50% רואים גרסה A, 50% גרסה B |
| Geo-blocking | חוסם או מפנה לפי מדינה | מדינות מסוימות רואות דף מיוחד |
מתי להשתמש: רוב הפרויקטים של Vibe Coders לא צריכים middleware בהתחלה. זה כלי מתקדם שרלוונטי בעיקר כשיש אימות משתמשים או צורך בהפניות מתוחכמות. אבל כדאי לדעת שהוא קיים כדי שכשה-AI ייצור אותו — תבינו מה הוא עושה ולמה.
טיפ לשוק הישראלי: אם אתם בונים אתר דו-לשוני (עברית + אנגלית), middleware הוא הדרך הנכונה לנתב מבקרים לשפה הנכונה. בקשו מ-AI: "הוסף middleware שמזהה את שפת הדפדפן ומפנה ל-/he או /en בהתאם."
איך middleware נראה? הנה דוגמה פשוטה:
// middleware.ts — בשורש הפרויקט
import { NextResponse } from 'next/server'
export function middleware(request) {
// אם מנסים לגשת ל-/dashboard בלי token
const token = request.cookies.get('session-token')
if (!token) {
// מפנים לדף ההתחברות
return NextResponse.redirect(new URL('/login', request.url))
}
// אחרת — ממשיכים כרגיל
return NextResponse.next()
}
// על אילו נתיבים הוא רץ
export const config = {
matcher: '/dashboard/:path*'
}
שוב — לא צריך לכתוב את זה. אבל כשה-AI מציע middleware, עכשיו אתם מבינים מה הוא עושה: בודק תנאי, ואם התנאי לא מתקיים — מפנה. ה-config.matcher אומר "הרץ את הבדיקה הזו רק על נתיבים שמתחילים ב-/dashboard".
חשבו על אתר שאתם רוצים לבנות. יש בו אזור מוגן שדורש התחברות? אם כן — middleware הוא הכלי. כתבו שורה אחת שמתארת מה ה-middleware שלכם צריך לבדוק.
SVG Diagram: המפה המלאה — מהקובץ לדפדפן
הנה סיכום ויזואלי של כל מה שלמדנו — איך בקשה מהדפדפן עוברת דרך כל שכבות הפרויקט:
המפה הזו היא הדבר הכי חשוב בפרק. אם אתם מבינים את הזרימה — דפדפן → middleware → router → layout → page (עם components, lib, hooks ו-public בצד) — אתם מבינים איך פרויקט Next.js עובד.
איך להשתמש במפה הזו בפרקטיקה:
- בעיה ב-URL? בדקו את app/ — ייתכן שחסר page.tsx או שהתיקייה לא במקום הנכון
- Header/Footer לא מופיעים? בדקו את layout.tsx — ייתכן שחסר import או שהקומפוננטה לא בתוך ה-body
- תמונה לא נטענת? בדקו שהיא ב-public/ והנתיב נכון (בלי "public" ב-URL)
- קומפוננטה לא עובדת? בדקו שה-import path נכון —
@/components/ui/buttonולא נתיב יחסי - API לא מגיב? בדקו שיש route.ts בתיקייה הנכונה ב-app/api/
כשמשהו לא עובד, 90% מהבעיות הן בעיות מיקום — קובץ לא במקום הנכון, import שגוי, או תיקייה חסרה. הבנת המפה הזו חוסכת שעות של דיבוג.
הסתכלו על הדיאגרמה למעלה ותענו: אם אתם רוצים להוסיף Google Analytics לאתר — באיזה קובץ תשימו את הקוד? (רמז: זה צריך לרוץ בכל דף)
איך לנהל שיחה עם AI על מבנה — 10 תרחישים
כל מה שלמדנו בפרק הזה מתמצה ליכולת אחת: לדעת להגיד ל-AI בדיוק איפה לשים כל דבר. הנה 10 תרחישים נפוצים — מה רוצים, ומה אומרים ל-AI:
| # | רוצה X | תגיד ל-AI Y |
|---|---|---|
| 1 | דף חדש באתר | "צור דף services ב-app/services/page.tsx" |
| 2 | קומפוננטת UI חדשה | "צור קומפוננטת testimonial ב-components/ui/testimonial.tsx" |
| 3 | Header משותף | "צור header ב-components/layout/header.tsx ותייבא אותו ב-layout.tsx" |
| 4 | דף מוצר דינמי | "צור דף מוצר ב-app/products/[id]/page.tsx עם dynamic route" |
| 5 | API endpoint | "צור API route ב-app/api/contact/route.ts שמקבל POST" |
| 6 | פונקציית עזר | "הוסף פונקציה ב-lib/utils.ts שמפרמטת תאריכים" |
| 7 | Custom hook | "צור hook ב-hooks/use-scroll-position.ts" |
| 8 | תמיכה בתמונות חיצוניות | "הוסף ל-next.config.ts תמיכה בתמונות מ-unsplash.com" |
| 9 | הפניה מ-URL ישן | "הוסף redirect ב-next.config.ts מ-/old ל-/new" |
| 10 | בדיקת הרשאות | "הוסף middleware.ts בשורש שבודק אם יש token לפני /dashboard" |
שימו לב לדפוס: כל prompt כולל שלושה דברים:
- מה לבנות — קומפוננטה, דף, API, hook
- איפה לשים — נתיב מדויק לקובץ (app/, components/, lib/)
- הקשר — מה הקובץ צריך לעשות ועם מה הוא מתחבר
זה נוסחת הזהב לשיחה עם AI על מבנה. כשאתם עוקבים אחרי הנוסחה הזו, ה-AI יוצר קוד שמתשלב בפרויקט במקום לצוף בחלל. זו הסיבה שהפרק הזה כל כך חשוב — הוא הופך אתכם ממשתמשי AI למנהלי פרויקט שעובדים עם AI.
בלי מבנה ברור בראש, הייתם אומרים "תוסיף כפתור" — וה-AI היה שם אותו איפה שנוח לו. עכשיו אתם אומרים "שים את הכפתור ב-components/ui/button.tsx" — וה-AI עושה בדיוק מה שאתם רוצים.
שאלות שעוזרות לתקן AI שטעה במיקום:
- "למה שמת את הכפתור בתוך page.tsx? תעביר אותו ל-components/ui/button.tsx ותייבא משם."
- "הקומפוננטה הזו משמשת 3 דפים — תעביר אותה ל-components/shared/ במקום לשכפל."
- "את ה-API key שמת בקוד — תעביר ל-.env.local ותגש אליו דרך process.env."
- "צור את הדף ב-app/blog/[slug]/page.tsx, לא ב-app/blog/page.tsx — זה route דינמי."
כשאתם מכירים את המבנה, אתם יכולים לבקר את העבודה של ה-AI בזמן אמת. זה לא שונה ממנהל שיודע מספיק על עיצוב כדי לבקר גרפיקאי — לא צריך לדעת לעצב, צריך לדעת מה נכון.
Prompt Template לתחילת כל פרויקט:
מבנה הפרויקט שלי:
- דפים: app/ directory עם App Router (לא pages/)
- קומפוננטות UI: components/ui/ (shadcn/ui)
- חלקים מבניים: components/layout/ (header, footer)
- פונקציות עזר: lib/
- Custom hooks: hooks/
- תמונות וקבצים סטטיים: public/images/
- API routes: app/api/
- הגדרות: layout.tsx בשורש app/
כשאתה יוצר קובץ חדש, ציין תמיד את הנתיב המלא.
אל תשים הכל בקובץ אחד — פצל לקומפוננטות.
שמרו את ה-prompt הזה. בכל פעם שמתחילים עבודה עם AI על פרויקט — הדביקו אותו בתחילת השיחה. ב-Cursor אפשר לשמור אותו בקובץ .cursorrules בשורש הפרויקט. ב-V0 אפשר לציין את זה בהנחיות הפרויקט. ב-Claude Code אפשר לשים ב-CLAUDE.md.
ההבדל בין prompt גנרי ל-prompt מדויק:
| Prompt גנרי (חלש) | Prompt מדויק (חזק) |
|---|---|
| "תוסיף טופס יצירת קשר" | "צור ContactForm ב-components/forms/contact-form.tsx, עם שדות name, email, message. השתמש ב-shadcn Input ו-Button. הוסף את הטופס ב-app/contact/page.tsx." |
| "תוסיף דף מוצרים" | "צור דף רשימת מוצרים ב-app/products/page.tsx, ודף מוצר בודד ב-app/products/[id]/page.tsx. השתמש ב-Card מ-shadcn להצגת כל מוצר." |
| "תעשה header" | "צור Header ב-components/layout/header.tsx עם לוגו (מ-public/logo.svg), ניווט ל-3 דפים, וכפתור CTA. תייבא אותו ב-app/layout.tsx." |
ההבדל ברור: ה-prompt המדויק אומר לא רק מה לבנות, אלא איפה לשים, במה להשתמש, ואיך לחבר. זו בדיוק הידיעה שהפרק הזה נתן לכם.
בחרו תרחיש אחד מהטבלה למעלה ונסו אותו עם ה-AI שלכם. האם הוא שם את הקובץ בדיוק במקום שביקשתם? אם כן — מעולה, אתם מנהלים את הפרויקט. אם לא — תקנו אותו.
סטארט-אפ ישראלי בתחום ה-FinTech ביקש מ-AI "תבנה לי אתר". התוצאה: קובץ page.tsx אחד עם 800 שורות — header, hero, features, pricing, footer — הכל ביחד. זה עבד, אבל כשביקשו לשנות רק את ה-header — היה צריך לחפש בתוך 800 שורות.
מה עשו: ביקשו מה-AI לפצל לפי מבנה מסודר:
components/layout/header.tsx— ניווט + לוגוcomponents/layout/footer.tsx— קישורים + copyrightcomponents/ui/pricing-card.tsx— כרטיס תמחור (נמצא בשימוש גם בדף pricing וגם ב-landing)components/sections/hero.tsx— סקשן ראשיcomponents/sections/features.tsx— סקשן יכולות
התוצאה: page.tsx ירד ל-30 שורות שרק מייבאות קומפוננטות. כל שינוי נעשה בקובץ נפרד, בלי לגעת בשאר. לקח אחד: אף פעם אל תקבלו קובץ של 500+ שורות מה-AI. תמיד בקשו לפצל.
הנוסחה: אם קובץ ארוך מ-200 שורות — כנראה שאפשר לפצל. אם ארוך מ-400 — בטוח שצריך. בקשו מה-AI: "פצל את הקומפוננטות לקבצים נפרדים ב-components/ ותייבא אותם ב-page.tsx." הוא ישמח לעשות את זה — פשוט צריך לבקש.
זמן: 20 דקות | רמה: מתחיל | תוצר: מפת מבנה מלאה עם הסברים
- בקשו מ-AI ליצור פרויקט:
צור מבנה תיקיות לפרויקט Next.js של אתר פורטפוליו. האתר צריך: עמוד בית, דף אודות, גלריית עבודות (עם דף לכל פרויקט), דף צור קשר, ובלוג. השתמש ב-App Router, shadcn/ui, Tailwind, ו-Lucide icons. - העתיקו את עץ התיקיות שה-AI ייצר לקובץ טקסט נפרד
- ליד כל תיקייה, כתבו הסבר של שורה אחת — מה התפקיד שלה? (השתמשו בטבלאות מהפרק)
- זהו 3 דברים שחסרים — האם יש loading.tsx? error.tsx? not-found.tsx? בקשו מה-AI להוסיף
- בדקו: האם הבלוג משתמש ב-dynamic route? האם הגלריה משתמשת ב-[id]?
תוצאה צפויה: מפת מבנה של 15-25 תיקיות וקבצים, עם הסבר ליד כל אחד. שלושה קבצים מיוחדים שהוספתם (loading, error, not-found). הבנה של למה הבלוג צריך [slug] דינמי.
מה לבדוק בפלט של ה-AI:
- האם יש
layout.tsxבשורש app/? (חייב להיות) - האם הגלריה משתמשת ב-
[id]dynamic route? (צריך) - האם הקומפוננטות ב-
components/או בתוך app/? (צריכות להיות ב-components/) - האם יש
public/לתמונות? (חייב להיות) - האם package.json כולל את shadcn, Lucide, ו-Tailwind? (צריך)
זמן: 15 דקות | רמה: בינוני | תוצר: מבנה routing מלא עם dynamic routes
- הגדירו 6 דפים שחנות אונליין צריכה:
- עמוד בית
- רשימת מוצרים (לפי קטגוריה)
- דף מוצר בודד
- עגלת קניות
- אודות / יצירת קשר
- תנאי שימוש / מדיניות פרטיות
- כתבו את מבנה התיקיות ב-app/ — אילו routes הם static ואילו dynamic?
- החליטו: האם צריך route group? (רמז: דפים "משפטיים" כמו terms ו-privacy יכולים להיות ב-(legal))
- בקשו מ-AI ליצור את המבנה ובדקו אם הוא תואם למה שתכננתם
- בונוס: בקשו מה-AI להוסיף middleware שבודק אם עגלת הקניות לא ריקה לפני גישה ל-checkout
תוצאה צפויה: מבנה שכולל app/products/[category]/page.tsx (קטגוריה), app/products/[category]/[id]/page.tsx (מוצר בודד), app/cart/page.tsx, app/(legal)/terms/page.tsx, ו-app/(legal)/privacy/page.tsx.
זמן: 15 דקות | רמה: בינוני | תוצר: package.json מוסבר עם הערות
- בקשו מ-AI:
הראה לי package.json מלא של פרויקט Next.js 15 עם: - shadcn/ui - Lucide icons - Tailwind CSS v4 - TypeScript כולל scripts ו-dependencies. - זהו 5 dependencies וכתבו ליד כל אחד מה הוא עושה (השתמשו בטבלה מהפרק)
- מצאו את ה-scripts: מה
npm run devעושה? מהnpm run build? - בקשו מה-AI להוסיף dependency חדש:
הוסף את framer-motion כ-dependency (לא devDependency). למה זה dependency ולא dev? - כתבו הסבר של שורה אחת — מה ההבדל בין dependencies ל-devDependencies?
תוצאה צפויה: הבנה שלמה של package.json — מה כל חלק עושה, למה framer-motion הוא dependency (כי הוא רץ בדפדפן) ולא devDependency, ויכולת לקרוא כל package.json בעתיד.
| תדירות | מה לעשות |
|---|---|
| יומי | כשנותנים prompt ל-AI — ציינו נתיב קובץ מדויק. תמיד. "שים את זה ב-components/ui/" במקום "תבנה לי כפתור". |
| יומי | אחרי שה-AI יוצר קבצים — סרקו את עץ התיקיות. האם הכל במקום הנכון? האם יש קובץ ענק שצריך לפצל? |
| שבועי | פתחו את ה-package.json של הפרויקט שלכם. יש dependencies שאתם לא מזהים? שאלו את ה-AI מה כל אחד עושה. |
| שבועי | בדקו שיש loading.tsx ו-error.tsx בתיקיות העיקריות — ניהול שגיאות וטעינה הם סימן לפרויקט מקצועי. |
| חודשי | סרקו את תיקיית components/ — יש קומפוננטות כפולות? קבצים שלא בשימוש? בקשו מ-AI לנקות. |
| חודשי | בדקו שה-next.config עדכני — גרסאות חדשות של Next.js מוסיפות יכולות. שאלו AI מה חדש. |
שננו את 5 התיקיות: app/ (דפים), components/ (UI), lib/ (לוגיקה), hooks/ (React hooks), public/ (קבצים סטטיים). אם אתם יודעים את החמישה האלה — אתם יודעים להגיד ל-AI איפה לשים כל דבר. זה ההבדל בין "תבנה לי אתר" (ו-AI מחליט הכל) לבין "תשים את ה-header ב-components/layout/header.tsx" (ואתם מחליטים).
- מה ההבדל בין page.tsx ל-layout.tsx, ולמה שניהם נמצאים בתיקיית app/? (רמז: אחד הוא התוכן, השני הוא העטיפה)
- אם יש לכם אתר עם 100 מוצרים — כמה קבצי page.tsx צריך לדפי המוצרים? (רמז: dynamic routes)
- מה ההבדל בין תיקייה [slug] לתיקייה (marketing)? (רמז: סוגריים מרובעים vs עגולים)
- למה node_modules לא עולה ל-Git, ואיך משחזרים אותו? (רמז: package-lock.json)
- אתם רוצים שה-AI יבנה header שמופיע בכל דף — איפה לשים אותו ואיפה לייבא? (רמז: components/ + layout.tsx)
אם עניתם נכון על 4 מתוך 5 — אתם מוכנים לפרק הבא.
הפרק הזה נתן לכם את המפה של כל פרויקט Next.js. התובנה המרכזית: כשאתם מבינים את המבנה, אתם לא רק קוראים קוד — אתם מנהלים את הפרויקט. במקום לתת ל-AI להחליט איפה לשים כל קובץ, אתם אומרים לו בדיוק איפה כל דבר הולך.
למדנו ש-app/ מנהלת את כל הדפים ושקבצים מיוחדים (page.tsx, layout.tsx, loading.tsx, error.tsx) שולטים בהתנהגות. ש-file-based routing הופך תיקיות ל-URLs, ש-dynamic routes עם סוגריים מרובעים פותרים את בעיית "הרבה דפים זהים עם מידע שונה", וש-route groups בסוגריים עגולים מארגנים בלי להשפיע על ה-URL.
ראינו ש-components/ מחזיקה UI, lib/ מחזיקה לוגיקה, hooks/ מחזיקה custom hooks, ו-public/ מחזיקה קבצים סטטיים. למדנו לקרוא package.json ולהבין מה כל dependency עושה, ולמה node_modules היא תיקייה שלא נוגעים בה ולא מעלים ל-Git.
בפרק הבא נלמד על Deployment — פריסת האתר לאוויר. Vercel, Netlify ו-Cloudflare Pages — כל אחד יודע לקחת את מבנה הפרויקט שלמדנו כאן ולהפוך אותו לאתר חי. כל ה-routing, הדפים, ה-middleware — הכל עולה ביחד. המבנה שלמדנו כאן קובע איך הפריסה עובדת.
- ☐ הבנתי את המבנה הבסיסי — app/, components/, lib/, hooks/, public/
- ☐ הבנתי מה page.tsx, layout.tsx, loading.tsx ו-error.tsx עושים
- ☐ הבנתי file-based routing — תיקייה = URL
- ☐ הבנתי dynamic routes — [id], [...slug], (groups)
- ☐ ביקשתי מ-AI ליצור פרויקט ובדקתי את מבנה התיקיות
- ☐ כתבתי prompt עם נתיב קובץ מדויק (לא סתם "תבנה לי X")
- ☐ קראתי package.json וזיהיתי dependencies מוכרים
- ☐ הבנתי את ההבדל בין dependencies ל-devDependencies
- ☐ הבנתי שלושת הכללים של node_modules (לא נכנסים, לא מעלים, אפשר למחוק)
- ☐ הבנתי מה @/ עושה ב-imports ומאיפה זה מוגדר
- ☐ הבנתי מה middleware עושה ואיפה הוא חי (שורש הפרויקט)
- ☐ השלמתי תרגיל 1 — מיפוי מבנה פרויקט
- ☐ השלמתי תרגיל 2 — routing לאתר חנות
- ☐ השלמתי תרגיל 3 — קריאת package.json
- ☐ שמרתי את טבלת ה-10 תרחישים כ-reference