עברית ו-RTL במערכות עסקיות: הבאגים שחוזרים שוב ושוב
חזרה לבלוג
web development·3 בספטמבר 2026·10 דק' קריאה·מאת יהונתן סעדיה

עברית ו-RTL במערכות עסקיות: הבאגים שחוזרים שוב ושוב

למה עברית נראית תקין במסך ומתהפכת ב-PDF, מה זה באמת סידור דו-כיווני, למה הפונט הוא הסיבה האמיתית לתווים חסרים, ובעיית המספרים המעורבים בעברית שאין ל-CSS פתרון עבורה.

עיקרי הדברים

  • הדפדפן מריץ עבורך את האלגוריתם הדו-כיווני. רוב ספריות ה-PDF והתמונות לא - וזו בדיוק הסיבה שעברית שנראית תקינה במסך יוצאת הפוכה בקובץ שנוצר.
  • תווים חסרים או ריבועים הם בעיית פונט, לא בעיית קידוד. הטקסט תקין; לפונט שביקשת מהרנדרר אין תווים בעברית. יש לצרף פונט שיש לו.
  • יש להשתמש בתכונות CSS לוגיות - start/end במקום left/right. פריסה שנבנתה בכיוונים פיזיים צריכה כתיבה מחדש ולא היפוך, כשהשפה מתחלפת.
  • טקסט עברי מעורב עם מספרים, מזהים ומונחים לועזיים הוא המקום שבו הדו-כיווניות באמת נושכת. מספרי חשבונית, טלפונים ומק"טים בתוך משפט עברי דורשים בידוד מפורש, לא תקווה.

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

1. הבאג הנפוץ ביותר: תקין במסך, הפוך ב-PDF

זו התלונה מספר אחת, וההסבר שלה פשוט ברגע שמבינים אותו.

הדפדפן מריץ עבורך את האלגוריתם הדו-כיווני (bidi). אתה נותן לו מחרוזת בעברית, והוא מחליט לבד איך לסדר אותה לתצוגה - כולל היכן מתחיל המשפט, לאן הולכים מספרים, ואיפה נופלים סימני פיסוק.

רוב ספריות ה-PDF לא עושות את זה. הן מציירות תווים לפי הסדר שקיבלו, משמאל לימין, בלי שום מודעות לכיווניות. התוצאה היא טקסט עברי שמופיע במהופך.

יש שתי גישות לפתרון, ובחירה ביניהן היא ההחלטה הארכיטקטונית האמיתית:

  • לרנדר דרך דפדפן. לבנות HTML ולתת למנוע דפדפן להפיק ממנו PDF. היתרון: מקבלים את ה-bidi, את פריסת ה-CSS ואת טעינת הפונטים בחינם, בדיוק כפי שנראה במסך. החיסרון: צריך דפדפן על השרת, וזה משקל תפעולי אמיתי.
  • לצייר ישירות בספריית PDF. מהיר וקל יותר לפריסה, אבל אז אתה אחראי לסידור הדו-כיווני בעצמך - צריך להעביר כל מחרוזת עברית דרך ספריית bidi שתסדר אותה מחדש לפני הציור.

שתי הגישות עובדות. מה שלא עובד הוא לצייר ישירות בלי סידור דו-כיווני ולקוות.

2. ריבועים ותווים חסרים - זו בעיית פונט

אם הטקסט יוצא כריבועים, סימני שאלה או ריק - זה כמעט אף פעם לא קידוד. הטקסט תקין; לפונט שהרנדרר משתמש בו פשוט אין תווים בעברית.

פונטי ברירת המחדל של ספריות PDF הם לרוב משפחות Latin-1 קלאסיות בלי כיסוי עברי כלל.

הפתרון הוא לצרף פונט עם כיסוי עברי אמיתי אל המערכת ולהצביע עליו מפורשות. שתי נקודות שקל לפספס:

  • לצרף את קובץ הפונט לפרויקט, לא להסתמך על מה שמותקן בשרת. מה שעובד במחשב הפיתוח שלך לא קיים על מכונת לינוקס נקייה, וזה מתגלה רק בייצור.
  • לבדוק רישוי. פונט שמוטמע בקובץ שנשלח ללקוח הוא הפצה, ולא כל רישיון פונט מתיר את זה.

3. פריסה: לוגי, לא פיזי

הטעות המבנית היא לבנות את הפריסה בכיוונים פיזיים - margin-left, padding-right, text-align: left - ואז לנסות "להפוך" הכול כשמגיעה עברית.

זה לא עובד, כי לא כל דבר צריך להתהפך. לוגו שאמור להישאר בצד אחד, אייקון של השמעה, ציר זמן - היפוך גורף שובר אותם.

הגישה הנכונה היא תכונות לוגיות: margin-inline-start במקום margin-left, text-align: start במקום left. הן מתהפכות לבד לפי dir, ומה שלא אמור להתהפך פשוט נשאר בכיוונים פיזיים - בכוונה ובמפורש.

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

4. הבאג שהכי קשה לאתר: טקסט מעורב

עברית טהורה עובדת. עברית עם מספרים, מזהים ומונחים לועזיים היא המקום שבו הדו-כיווניות באמת נושכת.

דוגמאות מהחיים: חשבונית מס 2026-00123 עבור ACME בע"מ, מספר טלפון בתוך משפט עברי, מק"ט אלפאנומרי, כתובת URL בהודעת WhatsApp.

מה שקורה: האלגוריתם הדו-כיווני מסווג כל תו לפי כיווניותו הטבעית, ומספרים וסימני פיסוק הם "ניטרליים" - הכיוון שלהם נקבע לפי מה שמסביבם. לכן מקף בין מספרים, סוגר, או נקודה בסוף משפט יכולים לקפוץ למקום הלא נכון, והמשמעות משתנה. מספר חשבונית שמוצג הפוך אינו בעיה אסתטית.

הפתרון: לבודד מפורשות. כל מחרוזת שאינה עברית טהורה בתוך משפט עברי - מזהה, מספר, שם באנגלית - צריכה לעטוף בבידוד כיווני, כדי שהיא תסודר כיחידה עצמאית ולא תושפע מהשכנים. ב-HTML זה נעשה עם אלמנט או תכונה שמכריזים על בידוד; בטקסט גולמי, עם תווי הבקרה המתאימים.

המקום שבו זה הכי מסוכן הוא טקסט שלא עובר דרך HTML בכלל - הודעת SMS, הודעת WhatsApp, שם קובץ, שורת נושא של מייל. שם אין CSS ואין dir, ורק תווי הבקרה עובדים.

מקומות שנשכחים

  • שמות קבצים. קובץ PDF עם שם בעברית עלול להישבר בכותרת ההורדה, ובמערכות מסוימות להישמר פגום. שם קובץ באנגלית עם מזהה מספרי הוא הבחירה הבטוחה.
  • ייצוא לאקסל. עמודה עברית תיראה תקינה, אבל עמודה מעורבת של טקסט ומספרים תסבול מאותה בעיית ניטרליות - ובנוסף, כיוון הגיליון עצמו הוא הגדרה נפרדת.
  • שורת נושא במייל. נושא בעברית דורש קידוד מתאים; בלעדיו חלק מהלקוחות יציגו ג'יבריש. גוף ההודעה עשוי להיראות מצוין בזמן שהנושא שבור.
  • לוגים. טקסט עברי בלוג טרמינל יוצג לפי כיווניות הטרמינל, שלרוב שגויה. זה לא באג במערכת - אבל זה יבלבל אותך בזמן ניפוי שגיאות אם לא תדע.

איך לבדוק שזה באמת עובד

הבדיקה במסך אינה מספיקה, כי המסך מקבל bidi בחינם. מה שבאמת צריך לבדוק:

  1. PDF שנוצר בייצור, לא בסביבת הפיתוח - שם חסרים הפונטים.
  2. רשומה עם טקסט מעורב - שם לקוח בעברית, מספר מסמך, וסכום. לא רק עברית טהורה.
  3. מייל שנשלח בפועל, כולל שורת הנושא, בשני לקוחות דואר שונים.
  4. הודעה שיוצאת בערוץ טקסט - SMS או WhatsApp - עם מזהה בתוך משפט עברי.
  5. המקרה הריק. שדה עברי חסר לא אמור להפיל את הפריסה או להשאיר סימן פיסוק תלוי.

ארבעת הבאגים למעלה מכסים כמעט את כל מה שמתגלה בפועל. הם לא קשים לתיקון - הם קשים לזיהוי, כי כולם נראים כמו "בעיה בעברית" בזמן שהם ארבעה דברים שונים לגמרי.

#RTL#Hebrew#PDF generation#internationalization#Israel

שאלות נפוצות

למה עברית נראית תקינה במסך והפוכה ב-PDF שנוצר?

כי הדפדפן מריץ עבורך את האלגוריתם הדו-כיווני של יוניקוד ורוב ספריות ה-PDF לא - הן מציירות תווים לפי הסדר שהתקבל, משמאל לימין. או לרנדר את ה-PDF דרך מנוע דפדפן, מה שנותן bidi ופריסת CSS בחינם, או להעביר כל מחרוזת עברית דרך ספריית סידור דו-כיווני לפני הציור.

למה עברית מוצגת כריבועים או סימני שאלה ב-PDF שלי?

זו בעיית פונט, לא קידוד. הטקסט תקין אבל לפונט שהרנדרר משתמש בו אין תווים בעברית - ברירות המחדל של ספריות PDF הן בדרך כלל משפחות לטיניות בלבד. יש לצרף לפרויקט פונט עם כיסוי עברי אמיתי במקום להסתמך על מה שמותקן במקרה בשרת, ולוודא שהרישיון מתיר הטמעה.

למה מספר חשבונית מופיע במקום הלא נכון בתוך משפט עברי?

כי מספרים וסימני פיסוק ניטרליים מבחינת כיוון - האלגוריתם הדו-כיווני קובע את כיוונם לפי התווים שמסביב. בתוך משפט עברי, מקף בין ספרות או נקודה בסוף יכולים לנחות בצד הלא נכון ולשנות את מה שהמזהה קורא. יש לעטוף כל רצף שאינו עברי - מזהים, מספרים, שמות לועזיים - בבידוד כיווני מפורש.

האם צריך להפוך את כל הפריסה לעברית?

לא - להשתמש בתכונות CSS לוגיות במקום. margin-inline-start ולא margin-left, ‏text-align: start ולא left, וכן הלאה. הן מתהפכות לבד לפי dir, בעוד שכל דבר שבאמת לא אמור להתהפך - מיקום לוגו, אייקון השמעה, ציר זמן - נשאר פיזי בכוונה. היפוך גורף שובר אותם.

איפה RTL נשבר מחוץ לדף האינטרנט?

בכל מקום שאין בו CSS ואין תכונת dir: הודעות SMS ו-WhatsApp, שורות נושא במייל, שמות קבצים, ייצוא לאקסל ולוגים בטרמינל. בערוצים האלה רק תווי בקרה של יוניקוד מספקים בידוד, ולכן טקסט מעורב של עברית ומזהים הוא המקרה שהכי סביר שיוצג שגוי - וגם המקרה שהכי פחות סביר שייבדק.

להמשך קריאה

שירות רלוונטי

פיתוח אתרים ומערכות

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

מידע נוסף

על הכותב

יהונתן סעדיה

מהנדס פרילנסר לאוטומציה, אתרים ו-MVP

אני יהונתן סעדיה, מהנדס בכיר שבונה אוטומציה עסקית, אתרים מותאמים ומוצרי MVP לעסקים קטנים ובינוניים בארה"ב, אירופה וישראל. המדריכים האלה נכתבים מתוך עבודה אמיתית עם לקוחות, לא מתיאוריה.

בוא נעבוד יחד

יש לך פרויקט דומה?

ספר לי מה אתה מנסה להפוך לאוטומטי או לבנות, ואומר לך מהי הדרך המהירה והאמינה ביותר ליישם את זה.