למה עמוד פנימי מחזיר 404 כשמרעננים (React ו-Vite)

העליתם את האתר, דף הבית נטען, הקישורים בתפריט עובדים. ואז מישהו שולח קישור ישיר ל-/about, או שאתם מרעננים עמוד פנימי, ומקבלים שגיאת 404. זו אחת התקלות הנפוצות ביותר באתרי React שנבנו עם Vite, כולל אתרים שנבנו בעזרת כלי AI. התיקון לוקח כמה דקות.

למה זה קורה

באתר "רגיל" לכל עמוד יש קובץ משלו בשרת. כשמבקשים את /about, השרת מחפש קובץ או תיקייה בשם הזה ומחזיר אותו.

באתרי React זה עובד אחרת. כל האתר נטען מקובץ אחד, index.html, והמעבר בין העמודים קורה בדפדפן, בלי לפנות לשרת. לכן כשלוחצים על קישור בתוך האתר, הכול עובד.

אבל כשמרעננים את /about, או נכנסים אליו ישירות מקישור, הדפדפן כן פונה לשרת ומבקש את הכתובת הזו. בשרת אין קובץ בשם about, והשרת עושה בדיוק מה שהוא אמור לעשות: מחזיר "לא נמצא".

הפתרון: להחזיר את index.html לכל כתובת שאינה קובץ

אומרים לשרת: אם מבקשים כתובת שאינה קובץ או תיקייה קיימים, תחזיר את index.html. משם קוד האתר קורא את הכתובת ומציג את העמוד הנכון.

בשרת שלנו הבקשות לאתר עוברות דרך Apache, ולכן עושים את זה עם קובץ בשם .htaccess בתיקיית האתר, ליד index.html:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>

מה כל שורה עושה

  • RewriteEngine On מפעיל את מנגנון שכתוב הכתובות.
  • RewriteBase / קובע שהאתר יושב בתיקייה הראשית של הדומיין.
  • RewriteRule ^index\.html$ - [L] אומר: אם ביקשו את index.html עצמו, אל תשנה כלום.
  • שתי שורות ה-RewriteCond בודקות שהכתובת אינה קובץ קיים (!-f) ואינה תיקייה קיימת (!-d).
  • RewriteRule . /index.html [L] מחזיר במקרה כזה את index.html.

התוצאה: תמונות, קובצי JavaScript ו-CSS ממשיכים להיטען כרגיל, כי הם קבצים קיימים. רק כתובות של עמודים מופנות ל-index.html.

איך מוסיפים את הקובץ

הדרך המומלצת: בתוך הפרויקט. שמים את הקובץ .htaccess בתיקיית public של הפרויקט. Vite מעתיק את מה שבתיקייה הזו לתוך dist בכל build, כך שהקובץ יעלה יחד עם האתר בכל פעם. אחרי ה-build בדקו שהקובץ אכן נמצא בתוך dist.

הדרך הישירה: בשרת. יוצרים קובץ חדש בשם .htaccess בתיקיית האתר, ליד index.html, ומדביקים את התוכן. אם בהעלאה הבאה אתם מוחקים את תוכן התיקייה לפני שמעלים, זכרו ליצור את הקובץ שוב.

אתר בתת-תיקייה

אם האתר לא יושב בתיקייה הראשית אלא בתת-תיקייה, למשל שם-העסק.co.il/app/, צריך לשנות שלושה דברים:

  1. בקובץ .htaccess: RewriteBase /app/, והשורה האחרונה הופכת ל-RewriteRule . /app/index.html [L].
  2. בהגדרות Vite: base: '/app/', כדי שהקבצים ייטענו מהנתיב הנכון. אחרי השינוי מריצים build מחדש.
  3. בראוטר של React: basename="/app" (למשל <BrowserRouter basename="/app">).

אם תשנו רק אחד מהם, תקבלו עמוד ריק או קבצים שלא נטענים.

טעויות נפוצות

  • שם קובץ שגוי. הקובץ נקרא בדיוק .htaccess, עם נקודה בהתחלה ובלי סיומת. במחשבי Windows הוא נשמר לפעמים בטעות כ-htaccess.txt.
  • הקובץ במקום הלא נכון. הוא צריך לשבת באותה תיקייה עם index.html, לא תיקייה אחת מעל ולא בתוך תיקיית dist שהועלתה בטעות כמו שהיא.
  • קובץ מוסתר שלא נכנס להעלאה. קבצים שמתחילים בנקודה מוסתרים בחלק מהמחשבים, ולפעמים נשמטים מקובץ ה-ZIP. בדקו שהקובץ באמת נמצא בתיקיית האתר, ליד index.html.
  • מטמון בדפדפן. אחרי התיקון, רעננו בחלון גלישה פרטית כדי לוודא שאתם לא רואים גרסה שמורה.

ואם אי אפשר לשנות את השרת?

יש אתרי React שמשתמשים בניתוב עם סימן # בכתובת, למשל /#/about. בשיטה הזו החלק שאחרי ה-# לא נשלח לשרת, ולכן אין 404. זה עובד, אבל הכתובות פחות יפות ופחות מתאימות לקידום בגוגל. אצלנו אין צורך בזה, כי קובץ .htaccess עובד.

איך בודקים שהתיקון עבד

  1. פותחים עמוד פנימי ישירות, למשל שם-העסק.co.il/about, ומרעננים.
  2. שולחים לעצמכם קישור לעמוד פנימי ופותחים אותו מהנייד.
  3. נכנסים לכתובת שבאמת לא קיימת, ובודקים שהאתר מציג עמוד "לא נמצא" משלו.

איזו חבילה מתאימה

לאתר React או Vite שיוצא כקבצים סטטיים אחרי build מתאימה חבילת אתרים סטטיים: עד 3 אתרים, 2GB נפח, 30GB תעבורה בחודש, SSL חינם וגיבוי יומי מחוץ לשרת, 14 ימים אחורה, החל מ-17.90 ₪ לחודש כולל מע"מ (בלי מייל). המדריך המלא להעלאה נמצא באיך מעלים לאוויר אתר שבניתם עם AI.

שאלות נפוצות

למה דף הבית עובד ורק עמודים פנימיים לא?
כי לדף הבית יש קובץ אמיתי, index.html. לעמודים הפנימיים אין קובץ בשרת, והם קיימים רק בקוד שרץ בדפדפן.
ה-.htaccess יפגע בתמונות או בקבצים?
לא. הכלל חל רק על כתובות שאינן קובץ או תיקייה קיימים.
צריך להוסיף את הקובץ שוב בכל העלאה?
אם שמתם אותו בתיקיית public של הפרויקט, הוא נכנס ל-dist אוטומטית בכל build.
זה רלוונטי גם לאתר וורדפרס?
לא. לוורדפרס יש הגדרות ניתוב משלה. המדריך הזה מיועד לאתרי React ו-Vite.

האתר שלכם מוכן לעלות?

בחרו חבילה ושימו אותו על הדומיין שלכם.

React, Vite, Apache, Windows וכל שם מוצר אחר שמוזכר כאן הם סימנים מסחריים של בעליהם. השימוש בהם הוא לצורך תיאור בלבד, ואין קשר רשמי בינם לבין Globalex.