המטרה
האתר של המרפאה היה אפליקציית Classic ASP ישנה, על אחסון שהמרפאה לא שולטת בו ולא יכולה לגבות. המטרה הייתה עיצוב מחדש מודרני ורספונסיבי ששומר על כל מה שהאתר הישן עשה - התפריט המלא, התוכן, טופס יצירת הקשר ששולח מייל למרפאה והדירוגים הקיימים בגוגל - ומאפשר לצוות לערוך טקסטים ותמונות בעצמו, בעברית ובשפות נוספות, עם SEO, GEO ו-AEO כמו שצריך.
הפתרון
Monorepo ב-pnpm עם שלוש אפליקציות וחבילה משותפת: אתר ציבורי ב-Nuxt 4 (SSR, @nuxtjs/i18n, Tailwind 4), API תוכן ב-Express 5 + MySQL, ופאנל ניהול ב-Vue 3 שמוגש תחת /admin. התוכן נשמר לפי שפה, כשהעברית היא מקור האמת וגם ברירת המחדל, כך שכל דף, שירות, פוסט ושאלה נפוצה מתורגמים בנפרד. התוכן של האתר הישן חולץ בסקריפט, יובא דרך ה-API של הניהול עם יומן גיבוי, והכתובות הישנות מופו להפניות 301. הפריסה רצה מ-GitHub Actions לאחסון cPanel משותף דרך ה-HTTPS API של cPanel, ואחריה בדיקת QA אוטומטית במובייל ובדסקטופ לכל דף.
עיקרי הדברים
- חמש שפות עם RTL ו-LTR, תוכן שמתורגם לכל דף
- צוות המרפאה עורך כל טקסט ותמונה מפאנל ניהול עם 20 מסכים
- התוכן מאתר ה-Classic ASP הישן הועבר בסקריפט, עם גיבויים ומפת כתובות ל-301
- QA אוטומטי על כל דף ברוחב מובייל ודסקטופ אחרי כל פריסה
האתגר
בשלד הראשון הכפתורים היו מתורגמים אבל לתוכן לא היה ממד של שפה, כך ש-/en ו-/ru היו מגישים את אותו טקסט עברי - תוכן כפול מבחינת מנוע חיפוש - וכמה שדות בפאנל נשמרו למפתחות שהאתר לא קורא.
קודם נכתב מסמך אפיון, תוקנו הקישורים השבורים בין השדות, הוגדרה סכמה קבועה לכל מקטע, ורק אחר כך נוסף תוכן לפי שפה עם חזרה לעברית, slug אחד לכל השפות ו-hreflang. בדיקות contract על ה-routes של הניהול ובדיקת parity לתרגומים שומרות על שני הצדדים מסונכרנים.
אחסון משותף בלי FTP או SFTP פתוח לעולם, ול-runners של GitHub אין IP קבוע שאפשר להכניס לרשימה לבנה.
ה-build ב-CI דוחף את התוצר ל-branch ייעודי לפריסה, והשרת מושך אותו דרך cron שמופעל מה-HTTPS API של cPanel, עם סנכרון אינקרמנטלי והגנות כך שפריסה שנכשלה לא מפילה את האתר.
התוכן של האתר הישן ו-23 הכתובות שלו שנמצאות באינדקס החזיקו את הדירוגים של המרפאה, על אחסון שאי אפשר לגבות.
הדפים המקוריים ומפת הכתובות נשמרו בארכיון, התוכן חולץ בסקריפט ויובא דרך ה-API של הניהול עם קבצי snapshot ויומן, ונוספו בדיקת התאמה מול האתר הישן ומנהל הפניות למיפוי ה-301.
תוכן מעורב RTL ו-LTR (מספרי טלפון, מיילים, חמש שפות) שובר את הפריסה בדרכים ש-build אף פעם לא תופס.
סקריפט QA ב-Playwright רץ אחרי כל פריסה על כל דף ברוחב מובייל ודסקטופ, ונכשל על גלילה לצדדים, טלפונים או מיילים שאינם לחיצים, בלוקים בעברית שמסודרים משמאל לימין, מספר h1 שגוי או תמונות שבורות.
מה נמסר
- אתר ציבורי ב-Nuxt 4 (SSR, חמש שפות, דפים מבוססי מקטעים)
- API תוכן ב-Express 5 + MySQL עם JWT, העלאת קבצים והגדרות SMTP מוצפנות
- פאנל ניהול ב-Vue 3 תחת /admin
- כלים לחילוץ ויבוא התוכן מהאתר הישן
- פריסה מ-GitHub Actions ל-cPanel ו-QA אחרי כל פריסה
- מסמכי אפיון ותוכניות מימוש
תוצאות
5
שפות
20
מסכי ניהול
23
כתובות ישנות שמופו
Self-serve
עריכת תוכן
מה זה לימד אותי
- כפתורים מתורגמים זה לא אתר רב-לשוני - התוכן עצמו צריך ממד של שפה, אחרת הכתובות הנוספות פוגעות ב-SEO
- קודם מתקנים את מיפוי השדות ורק אחר כך מוסיפים שפות, אחרת כל באג מוכפל במספר השפות
- באחסון משותף נעול, ה-API של לוח הבקרה ב-HTTPS יכול להיות ערוץ הפריסה האמין היחיד
