10 συνήθη λάθη i18n και πώς να τα αποφύγεις
Μάθε τα πιο συνηθισμένα λάθη διεθνοποίησης που κάνουν οι προγραμματιστές και πώς να τα διορθώσεις. Βελτίωσε την ποιότητα εντοπισμού/τοπικοποίησης της εφαρμογής σου με αυτές τις βέλτιστες πρακτικές.
Η διεθνικοποίηση (i18n) φαίνεται απλή — μέχρι να διαπιστώσεις ότι οι Γερμανοί χρήστες σου βλέπουν κομμένα κουμπιά, οι Ιάπωνες χρήστες λαμβάνουν αποκομμένα τμήματα φράσεων και οι αραβόφωνοι χρήστες βλέπουν πλήρως κατεστραμμένες διατάξεις. Δεν πρόκειται για εξαιρέσεις. Είναι οι προβλέψιμες συνέπειες συχνών λαθών που κάνουν οι περισσότερες ομάδες ανάπτυξης όταν αντιμετωπίζουν για πρώτη φορά τον εντοπισμό τοπικοποίησης. Σε αυτόν τον οδηγό θα καλύψουμε τα 10 πιο συνήθη i18n λάθη, θα εξηγήσουμε ακριβώς γιατί συμβαίνουν και θα σου δείξουμε βήμα προς βήμα πώς να τα διορθώσεις ένα προς ένα. Ακόμα κι αν κατασκευάζεις μια νέα εφαρμογή ή αναβαθμίζεις μια υπάρχουσα — η αποφυγή αυτών των παγίδων θα σου γλιτώσει εβδομάδες εντοπισμού σφαλμάτων.
Σφάλμα #1: Σκληροκωδικοποιημένες συμβολοσειρές
Οι σκληροκωδικοποιημένες συμβολοσειρές είναι η πιο βασική μορφή λαθών i18n. Συμβαίνει επειδή οι προγραμματιστές εστιάζουν αρχικά στο να κάνουν τα χαρακτηριστικά να λειτουργήσουν και σχεδιάζουν να τακτοποιήσουν αργότερα. Αλλά το «αργότερα» ποτέ δεν φτάνει, και ξαφνικά έχεις χιλιάδες συμβολοσειρές διασκορπισμένες σε εκατοντάδες αρχεία.
['Ρύθμισε το i18n-πλαίσιο πριν γράψεις την πρώτη γραμμή UI κώδικα', 'Χρησιμοποίησε ένα πρόσθετο linting για να εντοπίζεις σκληροκωδικοποιημένες συμβολοσειρές σε πρότυπα και συνιστώσες', 'Κράτα τα κλειδιά μετάφρασης περιγραφικά και οργάνωσέ τα ανά λειτουργία ή σελίδα']
Ρύθμισε το i18n-πλαίσιο πριν γράψεις την πρώτη γραμμή UI κώδικα
Χρησιμοποίησε ένα πρόσθετο linting για να εντοπίζεις σκληροκωδικοποιημένες συμβολοσειρές σε πρότυπα και συνιστώσες
Κράτα τα κλειδιά μετάφρασης περιγραφικά και οργάνωσέ τα ανά λειτουργία ή σελίδα
Ένα τυπικό σενάριο
Ένας προγραμματιστής γράφει άμεσα μια ετικέτα κουμπιού σε JSX: <button>Submit Order</button>.
Η εφαρμογή διατίθεται στα αγγλικά και λειτουργεί άψογα. Έξι μήνες αργότερα, η εταιρεία επεκτείνεται στη Γερμανία.
Η ομάδα τοπικοποίησης εντοπίζει πάνω από 2.000 σκληροκωδικοποιημένες συμβολοσειρές. Η αναβάθμιση διαρκεί 3 εβδομάδες και προκαλεί 47 σφάλματα.
Γιατί αυτό είναι πρόβλημα
Σε μια ώριμη βάση κώδικα, οι σκληροκωδικοποιημένες συμβολοσειρές μπορεί να φτάσουν χιλιάδες. Η εξαγωγή τους εκ των υστέρων απαιτεί να αγγίξεις κάθε αρχείο, να επανατεστάρεις κάθε συνιστώσα και να ρισκάρεις παντού παλινδρομήσεις.
Οι σκληροκωδικοποιημένες συμβολοσειρές είναι ενσωματωμένες απευθείας στον πηγαίο κώδικα, σε templates ή σε συνιστώσες. Δεν μπορούν να εξαχθούν, να μεταφραστούν ή να αλλάξουν κατά τη διάρκεια της εκτέλεσης χωρίς να αλλάξει ο ίδιος ο κώδικας.
Οι χρήστες σε μη αγγλόφωνες τοπικές εκδόσεις βλέπουν μη μεταφρασμένα UI στοιχεία ανάμικτα με μεταφρασμένο περιεχόμενο — μια χαώδης και μη επαγγελματική εντύπωση.
Έτσι το διορθώνεις
Μετάτρεψε όλες τις ορατές από τον χρήστη συμβολοσειρές από την αρχή σε αρχεία πόρων.
Ρύθμισε ένα πλαίσιο μετάφρασης (π.χ. next-intl, react-i18next, vue-i18n) πριν γράψεις την πρώτη σου συνιστώσα.
Δημιούργησε μια δομή αρχείων πόρων (π.χ. messages/de.json) και αναφέρεις όλες τις συμβολοσειρές με κλειδιά μετάφρασης όπως το t('checkout.submitButton').
Προσθέστε έναν κανόνα linting ή ένα προ-commit hook που σημαδεύει τα απλά string literals σε στοιχεία UI.
Σφάλμα #10: Μετάφραση όλων κυριολεκτικά
Δεν πρέπει όλα τα περιεχόμενα να μεταφράζονται. Τα εμπορικά ονόματα, τα ονόματα νομικών προσώπων, τεχνικοί όροι και ορισμένα ονόματα προϊόντων πρέπει να παραμείνουν στην αρχική τους γλώσσα. Η υπερβολική μετάφραση μπορεί να προκαλέσει νομικά προβλήματα, ασυνέπεια στη μάρκα και σύγχυση χρηστών.
["Διατήρησε ένα γλωσσάρι «μη μεταφράζεσαι» και μοιράσου το με όλους τους μεταφραστές", 'Χρησιμοποίησε κλειδωμένα τμήματα ή ξεχωριστά namespaces για εμπορικά ονόματα και νομικούς όρους', 'Πάντα παρείχε σημειώσεις πλαισίου για αμφισημείς συμβολοσειρές, ώστε να αποφεύγονται εσφαλμένες μεταφράσεις']
Διατήρησε ένα γλωσσάρι «μη μεταφράζεσαι» και μοιράσου το με όλους τους μεταφραστές
Χρησιμοποίησε κλειδωμένα τμήματα ή ξεχωριστά namespaces για εμπορικά ονόματα και νομικούς όρους
Πάντα παρείχε σημειώσεις πλαισίου για αμφισημείς συμβολοσειρές, ώστε να αποφεύγονται εσφαλμένες μεταφράσεις
Ένα τυπικό σενάριο
Ένα αρχείο μετάφρασης περιέχει το όνομα της εταιρείας 'CloudForge Inc.' και τον τεχνικό όρο 'OAuth 2.0 Token' ως κανονικές μεταφράσιμες συμβολοσειρές.
Ο ισπανικός μεταφραστής μεταφράζει το 'CloudForge' σε 'ForjaNube' και το 'OAuth 2.0 Token' σε 'ficha OAuth 2.0'.
Αποτέλεσμα: Οι χρήστες δεν βρίσκουν την εταιρεία με το πραγματικό της όνομα, και οι προγραμματιστές που διαβάζουν την ισπανική τεκμηρίωση μπερδεύονται από άγνωστους μεταφρασμένους τεχνικούς όρους.
Γιατί αποτελεί πρόβλημα
Ένα μεμονωμένο λάθος στη μετάφραση ενός εμπορικού ονόματος σε νομικό έγγραφο μπορεί να ακυρώσει συμβάσεις. Η διόρθωση υπερμεταφράσεων απαιτεί τον έλεγχο κάθε συμβολοσειράς σε κάθε γλώσσα — μια εργασία που διαρκεί αρκετές εβδομάδες.
Όταν όλες οι συμβολοσειρές αποστέλλονται χωρίς συμφραζόμενα στη μετάφραση, οι μεταφραστές μπορεί να μεταφράσουν εμπορικά ονόματα ('Apple' → 'Apfel'), νομικούς όρους ('GmbH' → 'LLC') ή τεχνικούς όρους που πρέπει να παραμείνουν στα αγγλικά.
Οι χρήστες δεν βρίσκουν τα προϊόντα με το γνωστό εμπορικό τους όνομα, τα νομικά έγγραφα παραπέμπουν στην εσφαμένη εταιρεία, και η τεχνική τεκμηρίωση γίνεται ακατανόητη όταν όροι όπως 'API Endpoint' μεταφράζονται.
Έτσι το διορθώνεις
Σημειώστε σαφώς τα μη μεταφραστέα περιεχόμενα και παρέχετε σημειώσεις πλαισίων για τους μεταφραστές.
Δημιουργήστε ένα γλωσσάριο 'μη μεταφράσιμο', το οποίο να περιλαμβάνει όλα τα εμπορικά ονόματα, ονόματα προϊόντων, νομικά πρόσωπα και τεχνικούς όρους που πρέπει να παραμείνουν αμετάβλητα.
Χρησιμοποιήστε ένα ξεχωριστό namespace ή ειδικά κλειδιά για μη μεταφραστικά περιεχόμενα. Πολλά εργαλεία i18n υποστηρίζουν 'κλειδωμένα' τμήματα που οι μεταφραστές δεν μπορούν να επεξεργαστούν.
Προσθέστε σχόλια/περιγραφές μεταφραστών στα αρχεία μετάφρασης που εξηγούν το πλαίσιο: 'Αυτό είναι εμπορικό όνομα — μη μεταφράζετε' ή 'Ειδικός όρος — παραμείνετε στα αγγλικά'.
Σφάλμα #2: Συγχώνευση συμβολοσειρών
Η ένωση προτάσεων από τμήματα φαίνεται λογική στα αγγλικά, αλλά δεν λειτουργεί σε άλλες γλώσσες. Η σειρά λέξεων, η γραμματική και η δομή των προτάσεων διαφέρουν σημαντικά ανά γλώσσα, με αποτέλεσμα οι συνενωμένες αλυσίδες να μην μπορούν να μεταφραστούν.
['Ποτέ μην δημιουργείτε προτάσεις συνδέοντας τμήματα μεταφρασμένων κειμένων', 'Χρησιμοποιήστε ονομαστικούς placeholders ('{name}') αντί για θέσης ({0}) για σαφήνεια', 'Παρέχετε σχόλια συμφραζομένων για τους μεταφραστές που εξηγούν τι περιέχει κάθε placeholder']
Μην συνδέεις ποτέ προτάσεις από μεταφρασμένα τμήματα
Χρησιμοποιήστε ονομαστικούς placeholders ('{name}') αντί για θέσης ({0}) για σαφήνεια
Παρέχετε συμφραζόμενα σχόλια για μεταφραστές, εξηγώντας τι περιέχει κάθε θέση αντικατάστασης.
Ένα τυπικό σενάριο
Ο προγραμματιστής γράφει: 'Έχετε ' + count + ' αντικείμενα στο καλάθι σας τύπου ' + cartType + ' cart' — λειτουργεί τέλεια στα αγγλικά.
Ο Γερμανός μεταφραστής λαμβάνει τρία ξεχωριστά αποσπάσματα και δεν μπορεί να σχηματίσει μια γραμματικά ορθή πρόταση, επειδή η σειρά των λέξεων πρέπει να αλλάξει.
Αποτέλεσμα: Οι γερμανόφωνοι χρήστες βλέπουν 'Έχετε 5 αντικείμενα στο καλάθι σας Standard' — χλωμό και μη επαγγελματικό.
Γιατί αυτό είναι ένα πρόβλημα
Κάθε συνδεδεμένη συμβολοσειρά είναι μια ωρολογιακή βόμβα. Με 20 γλώσσες και 50 συνδεδεμένες συμβολοσειρές, έχετε 1.000 πιθανά γραμματικά λάθη που πρέπει να διορθωθούν χειροκίνητα.
Η συνένωση κοινών συμβολοσειρών όπως 'Καλώς ήρθατε ' + userName + ', έχετε ' + count + ' νέα μηνύματα' προϋποθέτει συγκεκριμένη σειρά λέξεων. Οι μεταφραστές λαμβάνουν αποσπάσματα χωρίς συνοχή και δεν μπορούν να τα αναδιατάξουν.
Οι χρήστες βλέπουν γραμματικά λανθασμένες προτάσεις. Στα Γερμανικά το ρήμα συχνά βρίσκεται στο τέλος. Στα Αραβικά ολόκληρη η δομή είναι αντίστροφη. Το αποτέλεσμα διαβάζεται ως ανοησία.
Έτσι το διορθώνεις
Χρησιμοποιήστε παραμετρικά μηνύματα με ονομαστούς placeholders, ώστε οι μεταφραστές να μπορούν να αναδιατάξουν ολόκληρη την πρόταση.
Αντικαταστήστε τη σύνδεση με ένα μοναδικό κλειδί μηνύματος με placeholders: 'cart.summary': 'Έχεις {count} αντικείμενα στο '{cartType}' καλάθι σου'.
Μεταβιβάστε μεταβλητές ως παραμέτρους στη συνάρτηση μετάφρασης: t('cart.summary', { count: 5, cartType: 'Premium' }).
Οι μεταφραστές μπορούν τώρα να αναδιατάξουν ελεύθερα: 'Στο '{cartType}' καλάθι σου υπάρχουν {count} αντικείμενα' — γραμματικά σωστό γερμανικό.
Σφάλμα #3: Αγνόηση της πληθυντικής
Η αγγλική γλώσσα έχει δύο μορφές πληθυντικού: ενικός και πληθυντικός. Οι προγραμματιστές συχνά νομίζουν ότι όλες οι γλώσσες λειτουργούν με τον ίδιο τρόπο. Δεν ισχύει. Τα Πολωνικά έχουν τέσσερις μορφές, τα Αραβικά έξι, και ακόμη και γλώσσες όπως τα Γαλλικά χειρίζονται το μηδέν διαφορετικά από τα Αγγλικά.
['Πάντα χρησιμοποίησε το ICU MessageFormat ή μια αντίστοιχη βιβλιοθήκη για κείμενα που αλλάζουν ανάλογα με το πλήθος', 'Μην γράφεις ποτέ τη δική σου λογική για τον πληθυντικό — εμπιστεύσου τους κανόνες CLDR', 'Δοκίμασε πληθυντικά με τιμές όπως 0, 1, 2, 5, 21 και 100 για να καλύψεις όλες τις κατηγορίες']
Χρησιμοποιήσε πάντα το ICU MessageFormat ή μια αντίστοιχη βιβλιοθήκη για μετρήσιμο περιεχόμενο.
Μην γράφεις ποτέ τη δική σου λογική πληθυντικού — εμπιστεύσου τους κανόνες CLDR.
Δοκίμασε τα πληθυντικά με τιμές όπως 0, 1, 2, 5, 21 και 100 ώστε να καλυφθούν όλες οι κατηγορίες.
Ένα τυπικό σενάριο
Ο προγραμματιστής γράφει: count + (count === 1 ? ' Datei' : ' Dateien') — χειρίζεται σωστά τα γερμανικά.
Ο Πολωνός μεταφραστής χρειάζεται 4 μορφές: 1 plik, 2-4 pliki, 5-21 plików, 22-24 pliki. Ο απλός ternary δεν μπορεί να το εκφράσει.
Αποτέλεσμα: Οι Πολωνοί χρήστες βλέπουν '5 pliki' (λάθος μορφή) αντί για '5 plików' (σωστή μορφή), και η εφαρμογή φαίνεται ότι έχει καταστραφεί.
Γιατί αυτό αποτελεί πρόβλημα
Κάθε μετρήσιμο ουσιαστικό στην εφαρμογή σου χρειάζεται διαχείριση του πληθυντικού. Με 50 τέτοιες συμβολοσειρές και 20 γλώσσες πρόκειται για 1.000 κανόνες πληθυντικού — αδύνατον να τα διαχειριστείς χειροκίνητα.
Απλές εξετάσεις if/else (count === 1 ? 'Datei' : 'Dateien') αντιμετωπίζουν μόνο Γερμανικά/Αγγλικά. Ο CLDR ορίζει έως και 6 κατηγορίες πληθυντικού: zero, one, two, few, many και other. Κάθε γλώσσα χρησιμοποιεί διαφορετικό υποσύνολο.
Οι χρήστες βλέπουν γραμματικά λανθασμένα κείμενα όπως '1 Nachrichten' ή εντελώς λανθασμένες μορφές πληθυντικού. Σε επίσημα συμφραζόμενα, αυτό καταστρέφει την αξιοπιστία.
Έτσι το διορθώνεις
Χρησιμοποίησε το ICU MessageFormat, το οποίο υποστηρίζει εξ ορισμού όλους τους κανόνες πληθυντικού του CLDR.
Ορισμός μηνυμάτων με τη σύνταξη ICU: 'fileCount': '{count, plural, one {# Datei} other {# Dateien}}'.
Οι μεταφραστές παρέχουν όλες τις απαραίτητες μορφές πληθυντικού για τη γλώσσα τους. Πολωνικά: '{count, plural, one {# plik} few {# pliki} many {# plików} other {# pliku}}'.
Η βιβλιοθήκη i18n σου επιλέγει αυτόματα τη σωστή μορφή κατά την εκτέλεση, βάσει τους κανόνες CLDR της ενεργής locale.
Σφάλμα #4: Σταθερό πλάτος UI στοιχείων
Οι σχεδιαστές δημιουργούν pixel-ακριβείς διατάξεις στα αγγλικά, και οι προγραμματιστές τις υλοποιούν με σταθερό πλάτος. Αλλά το μεταφρασμένο κείμενο μπορεί να είναι δραματικά μακρύτερο ή συντομότερο. Το γερμανικό κείμενο είναι περίπου 30% μακρύτερο από τα αγγλικά, ενώ το κινεζικό κείμενο μπορεί να είναι κατά 50% συντομότερο.
['Μην χρησιμοποιείς ποτέ σταθερό πλάτος σε pixel για στοιχεία με μεταφρασμένο κείμενο', 'Πρόγραμμάτισε επέκταση κειμένου κατά 40% ως βάση — ορισμένες γλώσσες επεκτείνονται ακόμα περισσότερο', 'Χρησιμοποίησε CSS Flexbox ή Grid για διατάξεις που προσαρμόζονται σε μεταβλητό μήκος περιεχομένου']
Μην χρησιμοποιείς ποτέ σταθερό πλάτος σε pixel για στοιχεία με μεταφρασμένο κείμενο
Πρόγραμμάτισε επέκταση κειμένου κατά 40% ως βάση — ορισμένες γλώσσες επεκτείνονται ακόμα περισσότερο
Χρησιμοποίησε CSS Flexbox ή Grid για διατάξεις που προσαρμόζονται σε μεταβλητό μήκος περιεχομένου
Ένα τυπικό σενάριο
Ο σχεδιαστής δημιουργεί μια γραμμή πλοήγησης με 5 κουμπιά, το καθένα ακριβώς 100px πλάτος — φαίνεται τέλεια στα αγγλικά.
Γερμανική μετάφραση: το 'Settings' γίνεται 'Einstellungen' (13 έναντι 8 χαρακτήρων), το 'Submit' γίνεται 'Absenden' (8 έναντι 6). Η γραμμή πλοήγησης υπερχειλίζει.
Αποτέλεσμα: Στις κινητές συσκευές τα κουμπιά στοιβάζονται το ένα πάνω στο άλλο ή το κείμενο κόβεται, γεγονός που καθιστά την πλοήγηση αχρήστη για Γερμανούς χρήστες.
Γιατί αυτό είναι ένα πρόβλημα
Κάθε στοιχείο με σταθερό πλάτος αποτελεί πιθανό σημείο ρήξης. Μια τυπική εφαρμογή έχει εκατοντάδες κουμπιά, ετικέτες και κάρτες, που όλες πρέπει να αντέχουν την επέκταση του κειμένου.
Κοντέινερ με σταθερό πλάτος (width: 120px) και κουμπιά σταθερού μεγέθους κόβονται ή ξεπερνούν όταν το κείμενο επεκτείνεται. Το CSS overflow: hidden κρύβει το περιεχόμενο σιωπηλά, ενώ overflow: visible καταστρέφει τη διάταξη.
Οι χρήστες βλέπουν κομμένες ετικέτες όπως 'Einstellu...' αντί για 'Einstellungen', ή κουμπιά που επικαλύπτουν γειτονικά στοιχεία. Οι κρίσιμες ενέργειες γίνονται ακατανόητες ή μη κλικάσιμες.
Έτσι το διορθώνετε
Σχεδίασε και υλοποίησε ευέλικτους σχεδιασμούς που προσαρμόζονται στο μήκος περιεχομένου σε όλα τα locales.
Αντικαταστήστε τις σταθερές διαστάσεις του πλάτους με min-width, max-width και ευέλικτους σχεδιασμούς. Χρησιμοποιήστε CSS Grid ή Flexbox για να κατανέμετε δυναμικά τον χώρο.
Ρύθμισε το κοντέινερ κειμένου ώστε να σπάει σε επόμενη γραμμή: χρησιμοποίησε overflow-wrap: break-word και απόφυγε το white-space: nowrap σε μεταφράσιμο περιεχόμενο.
Δοκιμάστε το UI σας με ψευδο-τοπικοποίηση, η οποία επεκτείνει όλα τα strings κατά 40% για να προσομοιώσετε την πλέον δυσμενή περίπτωση — πριν στείλετε τα strings σε μεταφραστές.
Σφάλμα #5: Μορφοποίηση ημερομηνιών και αριθμών
Τα δεδομένα και οι αριθμοί φαίνονται δυνητικά παγκόσμιοι. Αλλά το 01/02/2025 σημαίνει στις ΗΠΑ τη 2η Ιανουαρίου και στην Ευρώπη την 1η Φεβρουαρίου. Τα κόμματα και οι τελίτσες αλλάζουν τη σημασία τους στους αριθμούς: 1,000.50 (ΗΠΑ) έναντι 1.000,50 (Γερμανία). Το να το κάνεις λάθος οδηγεί σε σύγχυση, λάθη στα δεδομένα και απώλεια εμπιστοσύνης.
['Μορφοποιήστε δεδομένα ή αριθμούς ποτέ χειροκίνητα με templates συμβολοσειρών — χρησιμοποιήστε πάντα τα API Intl', 'Αποθηκεύστε όλα τα δεδομένα σε ISO 8601 και τα νομισματικά ποσά στη μικρότερη μονάδα (σεντ) εσωτερικά', 'Δοκιμάστε τοπικές ρυθμίσεις που χρησιμοποιούν διαφορετικούς δεκαδικούς διαχωριστές, διαφορετικές ακολουθίες ημερομηνιών και ημερολογιακά συστήματα']
Ποτέ μην μορφοποιείτε δεδομένα ή αριθμούς χειροκίνητα με templates συμβολοσειρών — χρησιμοποιήστε πάντα τα Intl API.
Αποθήκευσε όλα τα δεδομένα σε ISO 8601 και τα νομίσματα στην μικρότερη μονάδα (Cent) εσωτερικά
Δοκιμάστε τοπικές ρυθμίσεις που χρησιμοποιούν διαφορετικούς δεκαδικούς διαχωριστές, διαφορετικές ακολουθίες ημερομηνιών και ημερολογιακά συστήματα
Ένα τυπικό σενάριο
Ο προγραμματιστής μορφοποιεί μια ημερομηνία ως MM/DD/YYYY και μια τιμή ως $1,234.50 — σωστό για τους χρήστες στις ΗΠΑ.
Ένας Γερμανός χρήστης βλέπει την ημερομηνία 03/04/2025 και την ερμηνεύει ως 3 Απριλίου (DD/MM/YYYY κανόνας). Η τιμή $1,234.50 φαίνεται ότι θα έπρεπε να είναι 1.234,50.
Αποτέλεσμα: Ο χρήστης κλείνει πτήση για λάθος ημερομηνία και αμφισβητεί το μορφότυπο τιμής. Τα αιτήματα τεχνικής υποστήριξης αυξάνονται κατά 15% στην γερμανική αγορά.
Γιατί αυτό είναι πρόβλημα
Η μορφοποίηση ημερομηνιών και αριθμών αφορά κάθε εμφάνιση δεδομένων στην εφαρμογή σου: πίνακες, διαγράμματα, φόρμες, τιμολόγια, αναφορές. Μία παγκόσμια διόρθωση καλύπτει εκατοντάδες περιπτώσεις.
Οι σκληροκωδικοποιημένες συμβολοσειρές μορφής, όπως toLocaleDateString('en-US'), ή η χειροκίνητη διαμόρφωση με template literals παραβλέπουν την πραγματική Locale του χρήστη. Ακόμη και η σωστή Locale αλλά το λανθασμένο ημερολογιακό σύστημα (Gregorian vs. Hijri) προκαλεί προβλήματα.
Οι χρήστες διαβάζουν λανθασμένα δεδομένα και εισάγουν δεδομένα σε λάθος μορφή. Ένας ευρωπαίος χρήστης που βλέπει 03/04/2025 μπορεί να το ερμηνεύσει ως 3 Απριλίου αντί για 4 Μαρτίου — χαμένες προθεσμίες ή λανθασμένες κρατήσεις.
Έτσι το διορθώνεις
Χρησιμοποιήστε τη ενσωματωμένη Intl-API ή μια βιβλιοθήκη μορφοποίησης ανά locale για όλα τα δεδομένα, χρόνους, αριθμούς και νομίσματα.
Αντικαταστήστε τη χειροκίνητη μορφοποίηση με Intl.DateTimeFormat(locale) για ημερομηνίες και Intl.NumberFormat(locale, { style: 'currency', currency }) για τιμές.
Αποθηκεύστε εσωτερικά δεδομένα σε μορφή ISO 8601 (YYYY-MM-DD) και μορφοποιήστε τα μόνο για εμφάνιση με τη Locale του χρήστη.
Δοκιμάστε κρίσιμες εμφανίσεις ημερομηνιών/αριθμών με τουλάχιστον πέντε διαφορετικές τοπικές ρυθμίσεις: en-US, de-DE, ja-JP, ar-SA και zh-CN, ώστε να καλύψετε τις βασικές μορφοποιήσεις.
Σφάλμα #6: Ξεχασμένες οι γλώσσες RTL
Οι γλώσσες από τα δεξιά προς τα αριστερά (RTL), όπως Αραβικά, Εβραϊκά και Περσικά, χρησιμοποιούνται από πάνω από 500 εκατομμύρια ανθρώπους. Παρ' όλα αυτά, οι περισσότερες εφαρμογές σχεδιάζονται μόνο για διατάξεις από αριστερά προς τα δεξιά (LTR). Η υποστήριξη RTL δεν σημαίνει απλώς γυρισμένο κείμενο — ολόκληρο το UI πρέπει να αντικατοπτριστεί.
['Χρησιμοποιήστε από την πρώτη ημέρα μόνο λογικές CSS-ιδιότητες (inline-start/end, block-start/end)', "Δοκιμάστε την εφαρμογή σας με dir='rtl' στο στοιχείο HTML σε κάθε sprint-ανασκόπηση", 'Δημιουργήστε μια λίστα ελέγχου RTL για πλοήγηση, εικονίδια, φόρμες και ενδείξεις προόδου']
Χρησιμοποιήστε από την πρώτη ημέρα μόνο λογικές CSS-ιδιότητες (inline-start/end, block-start/end)
Δοκιμάστε την εφαρμογή σας με dir='rtl' στο στοιχείο HTML σε κάθε sprint-ανασκόπηση
Δημιουργήστε μια λίστα ελέγχου RTL για πλοήγηση, εικονίδια, φόρμες και ενδείξεις προόδου
Ένα τυπικό σενάριο
Ο προγραμματιστής χρησιμοποιεί margin-left: 16px και text-align: left σε ολόκληρη την εφαρμογή — τυπική πρακτική LTR.
Η εφαρμογή ξεκινά στη Σαουδική Αραβία. Τα βέλη επιστροφής δείχνουν προς τα μπρος, τα πλευρικά μενού εμφανίζονται στην λάθος πλευρά και τα αριθμητικά δεδομένα ευθυγραμμίζονται λάθος.
Αποτέλεσμα: Οι Αραβικοί χρήστες εγκαταλείπουν την εφαρμογή μετά από 30 δευτερόλεπτα. Η ομάδα χρειάζεται 4 εβδομάδες για μια έκτακτη αναδιάρθρωση CSS προκειμένου να επιλυθεί το πρόβλημα.
Γιατί αυτό αποτελεί πρόβλημα
Η υποστήριξη RTL αφορά κάθε ξεχωριστό στοιχείο στην εφαρμογή σου. Η προσθήκη του RTL εκ των υστέρων συνήθως απαιτεί την επαναγραφή του 30-50% όλων των κανόνων CSS και τον έλεγχο κάθε εικονιδίου και διάταξης.
Ιδιοτήτες CSS όπως margin-left, padding-right, text-align: left και float: left σκληροκωδικοποιούν την κατεύθυνση. Εικονίδια με ένδειξη κατεύθυνσης (βέλη, δείκτες προόδου) δείχνουν προς τη λάθος κατεύθυνση. Ακόμη και οι τιμές border-radius πρέπει να καθρεφρίζονται.
Οι χρήστες που χρησιμοποιούν αραβικά βλέπουν την πλοήγηση στη λάθος γωνία, η γραμμή προόδου κινείται προς τα πίσω και το κείμενο συγκρούεται με τα στοιχεία UI. Η εφαρμογή φαίνεται ξένη και μη χρηστική.
Έτσι το διορθώνεις
Χρησιμοποιήστε λογικές ιδιότητες CSS και ελέγξτε από την αρχή τη διάταξη RTL.
Αντικαταστήστε όλες τις φυσικές ιδιότητες CSS με λογικές αντίστοιχες: margin-left → margin-inline-start, padding-right → padding-inline-end, text-align: left → text-align: start.
Ορίστε το χαρακτηριστικό dir στο ριζικό HTML σας ανάλογα με την ενεργή locale. Χρησιμοποιήστε την ψευδο-κλάση CSS :dir(rtl) για RTL-ειδικές ρυθμίσεις.
Έλεγξε όλα τα εικονίδια για τη σημασία της κατεύθυνσης. Αντικατάστησε τα εικονίδια που εξαρτώνται από την κατεύθυνση με καθρέφτισμένες εκδόσεις ή χρησιμοποίησε CSS transform: scaleX(-1) για περιβάλλοντα RTL.
Σφάλμα #7: Εικόνες με κείμενο
Η ενσωμάτωση κειμένου μέσα σε εικόνες — είτε σε hero banners, κουμπιά, διαγράμματα ή στιγμιότυπα οθόνης — αποτελεί εφιάλτη τοπικοποίησης. Κάθε εικόνα με κείμενο πρέπει να δημιουργείται εκ νέου για κάθε γλώσσα, κάτι που αυξάνει τα κόστη σχεδίασης και καθυστερεί τις κυκλοφορίες.
['Παρακαλώ μην ενσωματώνετε ποτέ μεταφράσιμο κείμενο απευθείας σε raster εικόνες (PNG, JPG).', 'Χρησιμοποιήστε επικάλυψη κειμένου CSS σε εικόνες φόντου για τα hero banners και CTAs.', 'Αυτόματοποιήστε τη δημιουργία στιγμιότυπων οθόνης για καταχωρίσεις App Store και σελίδες μάρκετινγκ.']
Μην ενσωματώνετε ποτέ μεταφρασμένο κείμενο απευθείας σε raster εικόνες (PNG, JPG).
Χρησιμοποιήστε overlays κειμένου CSS πάνω από εικόνες φόντου για τα hero banners και τα CTA.
Αυτόματοποιήστε τη δημιουργία στιγμιότυπων οθόνης για καταχωρίσεις στο App Store και σελίδες μάρκετινγκ
Ένα τυπικό σενάριο
Ένας σχεδιαστής δημιουργεί ένα προωθητικό πανό με το κείμενο 'Start Your Free Trial' ενσωματωμένο απευθείας στην εικόνα.
Η ομάδα τοπικοποίησης μεταφράζει όλα τα UI-κείμενα, αλλά το banner στη γερμανική σελίδα εξακολουθεί να εμφανίζει αγγλικό κείμενο.
Αποτέλεσμα: Η γερμανική αρχική σελίδα έχει ένα ενοχλητικό αγγλικό banner. Η δημιουργία τοποποιημένων banners για 15 γλώσσες χρειάζεται 3 ημέρες σχεδιαστικής εργασίας και καθυστερεί το λανσάρισμα.
Γιατί αυτό είναι πρόβλημα
Μια τυπική σελίδα μάρκετινγκ έχει 5-10 εικόνες με κείμενο. Με 15 γλώσσες, αυτό σημαίνει 75-150 παραλλαγές εικόνων που πρέπει να δημιουργηθούν, να συντηρηθούν και να ενημερώνονται σε κάθε αλλαγή σχεδίασης.
Κείμενο ενσωματωμένο σε εικόνες (PNG, JPG, SVG με ενσωματωμένο κείμενο) δεν μπορεί να εξαχθεί από εργαλεία μετάφρασης. Κάθε τοποποιημένης έκδοσης απαιτεί από έναν σχεδιαστή να επεξεργαστεί χειροκίνητα το αρχικό αρχείο, να το εξάγει και να το ανεβάσει.
Οι χρήστες βλέπουν εικόνες με κείμενο σε ξένη γλώσσα ή, χειρότερα, ένα μείγμα μεταφρασμένου UI και μη μεταφρασμένων εικόνων. Αυτό φαίνεται ασυνέπεια και υπονομεύει την εμπιστοσύνη στη μάρκα.
Έτσι το διορθώνεις
Χωρίστε το κείμενο από τις εικόνες χρησιμοποιώντας επικάλυψεις CSS, SVG με μεταφράσιμα στοιχεία κειμένου ή δυναμική δημιουργία εικόνων
Χρησιμοποιήστε CSS για να τοποθετήσετε μεταφρασμένο κείμενο πάνω από εικόνες φόντου: τοποθετήστε το επίπεδο κειμένου με απόλυτη θέση πάνω από τον κοντέινερ της εικόνας.
Για Infografika ή διαγράμματα χρησιμοποιήστε SVG με στοιχεία <text> που αναφέρονται σε μεταφραστικά κλειδιά αντί να ενσωματώνετε απλά κείμενα.
Για τα App-Screenshots σε διαφημιστικά υλικά αυτοματοποιήστε τη λήψη στιγμιότυπων οθόνης με εργαλεία όπως το Fastlane (Mobile) ή Playwright (Web), ώστε να λαμβάνετε στιγμιότυπα οθόνης σε κάθε locale.
Σφάλμα #8: Οι ελλείπουσες μεταφράσεις δεν αντιμετωπίζονται
Οι μεταφράσεις κατά τη διάρκεια της ανάπτυξης παραμένουν πάντα ελλιπείς. Νέα χαρακτηριστικά προσθέτουν γρήγορα strings, ενώ οι μεταφραστές δεν μπορούν να τα μεταφράσουν όλα. Χωρίς σωστή διαχείριση fallback, οι ελλείπουσες μεταφράσεις προκαλούν σφάλματα, κενά στοιχεία UI ή ακατέργαστους μεταφραστικούς κλειδιά που εμφανίζονται στους χρήστες.
['Ρυθμίστε πάντοτε τουλάχιστον μια γλώσσα fallback στο i18n-σύστημά σας', 'Καταγράψτε τα ελλείποντα κλειδιά μετάφρασης στο σύστημα παρακολούθησης σας για την ιχνηλάτηση', 'Ορίστε ένα ελάχιστο επίπεδο κάλυψης μετάφρασης πριν από το να ενεργοποιηθεί μια locale']
Ρυθμίστε πάντοτε τουλάχιστον μια γλώσσα fallback στο i18n-σύστημά σας
Καταγράψτε τα κλειδιά μετάφρασης που λείπουν στο σύστημα παρακολούθησης σας για την ιχνηλάτηση
Ορίστε ένα ελάχιστο ποσοστό κάλυψης μεταφράσεων πριν μια locale τεθεί σε ζωντανή λειτουργία
Μια τυπική περίπτωση
Ο προγραμματιστής προσθέτει μια νέα ενότητα 'Premium Features' με 15 νέα κλειδιά μετάφρασης. Η αγγλική έκδοση διατίθεται άμεσα.
Οι γαλλικές μεταφράσεις δεν είναι ακόμη έτοιμες. Η γαλλική σελίδα εμφανίζει ακατέργαστα κλειδιά: 'premium.feature1.title', 'premium.feature1.description'.
Αποτέλεσμα: Οι Γάλλοι χρήστες βλέπουν μια κατεστραμμένη σελίδα γεμάτη ονόματα κλειδιών της πλευράς του προγραμματιστή. Η ομάδα υποστήριξης λαμβάνει δεκάδες αναφορές σφαλμάτων.
Γιατί αυτό είναι ένα πρόβλημα
Όσο μεγαλώνει η εφαρμογή σου, τόσο μεγαλύτερο γίνεται το κενό μεταξύ των αγγλικών strings και των μεταφράσεών τους σε άλλες γλώσσες. Μια εφαρμογή με 100 γλώσσες και 2.000 strings θα μπορούσε ανά πάσα στιγμή να έχει 10.000+ ελλείπουσες μεταφράσεις.
Χωρίς μηχανισμό fallback, το ελλείπον μεταφραστικό κλειδί επιστρέφει undefined, null ή τον ακατέργαστο string του κλειδιού (π.χ. 'checkout.confirmButton'). Οι template engines μπορεί να ρίξουν σφάλματα, να κρασάρει η σελίδα ή να μην αποδώσουν τίποτα.
Οι χρήστες βλέπουν κατεστραμμένο UI: κενά κουμπιά, ελλείποντες ετικέτες ή ακατάληπτους κωδικούς όπως 'nav.settings.title' αντί για πραγματικό κείμενο. Αυτό είναι μπερδεμένο και μη επαγγελματικό.
Έτσι το διορθώνεις
Ρυθμίστε μια αξιόπιστη αλυσίδα fallback και παρακολουθήστε την επάρκεια μεταφράσεων σε όλες τις γλώσσες.
Ρυθμίστε μια αλυσίδα fallback στη διαμόρφωση i18n σας: τα ελλείποντα γαλλικά (fr) κλειδιά θα επιστρέφουν αυτόματα στα αγγλικά (en).
Προσθέστε έναν Missing-Key χειριστή που θα καταγράφει τα μη μεταφρασμένα κλειδιά στο σύστημα παρακολούθησης σας (π.χ. Sentry, Datadog) χωρίς να διακόπτει την εμπειρία χρήστη.
Δημιουργήστε έναν πίνακα ελέγχου κάλυψης μεταφράσεων που παρακολουθεί το ποσοστό ολοκλήρωσης ανά locale και εμποδίζει τις κυκλοφορίες αν η κάλυψη πέσει κάτω από ένα όριο (π.χ. 95%).
Σφάλμα #9: Προβλήματα κωδικοποίησης χαρακτήρων
Τα προβλήματα κωδικοποίησης χαρακτήρων είναι ο ήσυχος δολοφόνος της τοπικοποίησης. Όλα φαίνονται καλά στα αγγλικά και σε ευρωπαϊκές γλώσσες, αλλά μόλις προσθέσεις Κινέζικα, Ιαπωνικά, Κορεάτικα, Αραβικά ή Emoji, εμφανίζονται διεστραμμένα σύμβολα (Mojibake). Αυτά τα σφάλματα είναι δύσκολο να ανιχνευθούν.
['Χρησιμοποιήστε UTF-8 παντού — αρχεία πηγαίου κώδικα, βάση δεδομένων, αποκρίσεις API και μετα-ετικέτες HTML', 'Χρησιμοποιήστε utf8mb4 στη MySQL (όχι utf8) για να υποστηρίξετε ολόκληρο το εύρος Unicode, συμπεριλαμβανομένων Emoji', 'Δοκιμάστε πραγματικό περιεχόμενο σε CJK, Κινέζικα, Ιαπωνικά και Emoji, για να εντοπίσετε προβλήματα κωδικοποίησης νωρίς']
Χρησιμοποιήστε κωδικοποίηση UTF-8 παντού — αρχεία προέλευσης, βάση δεδομένων, απαντήσεις API και μετα-ετικέτες HTML
Χρησιμοποιήστε utf8mb4 στη MySQL (όχι utf8) για να υποστηρίξετε ολόκληρο το εύρος Unicode, συμπεριλαμβανομένων Emoji
Δοκιμάστε πραγματικό περιεχόμενο σε CJK, Κινέζικα, Ιαπωνικά και Emoji, για να εντοπίσετε προβλήματα κωδικοποίησης νωρίς
Μια τυπική περίπτωση
Ο προγραμματιστής ρυθμίζει μια βάση δεδομένων MySQL με latin1-collation (ο παλιός προεπιλεγμένος). Ο κώδικας της εφαρμογής χρησιμοποιεί UTF-8.
Οι Ιάπωνες χρήστες εγγράφονται με το πραγματικό τους όνομα. Η βάση δεδομένων αποθηκεύει '田中太郎' ως κατεστραμμένα bytes.
Αποτέλεσμα: Το προφίλ χρήστη εμφανίζει κατεστραμμένο κείμενο. Ακόμη χειρότερο: η αναζήτηση και η ταξινόμηση αποτυγχάνουν για όλα τα ονόματα CJK, με αποτέλεσμα χιλιάδες χρήστες να επηρεάζονται.
Γιατί αυτό αποτελεί πρόβλημα
Τα προβλήματα κωδικοποίησης εξαπλώνονται σε ολόκληρο το stack σας. Μια εσφαλμένα ρυθμισμένη collation βάσης δεδομένων μπορεί να καταστρέψει εκατομμύρια εγγραφές — η επιδιόρθωση απαιτεί ακριβές migrations δεδομένων.
Ανομοιογενής κωδικοποίηση σε ολόκληρο το stack — UTF-8 στα αρχεία πηγαίου κώδικα, Latin-1 στη βάση δεδομένων και Windows-1252 στις αποκρίσεις API — καταστρέφει πολυβάθμιους χαρακτήρες. Μία μόνο λανθασμένη στρώση μετατρέπει '日本語' σε '????' ή '日本èª'.
Οι χρήστες βλέπουν διεστραμμένα κείμενα, ερωτηματικά ή κενά πλαίσια όπου θα έπρεπε να βρίσκεται η γλώσσα τους. Στην χειρότερη περίπτωση, οι εισαγόμενες τιμές σε φόρμες μπορεί να καταστραφούν μόνιμα στη βάση δεδομένων.
Έτσι το διορθώνεις
Επιβάλλετε ομοιόμορφα την κωδικοποίηση UTF-8 σε κάθε επίπεδο της στοίβας εφαρμογών σας.
Ρυθμίστε όλα τα αρχεία πηγαίου κώδικα σε UTF-8 (διαμορφώστε τον επεξεργαστή σας και το .editorconfig). Προσθέστε <meta charset='UTF-8'> στα HTML σας και 'Content-Type: application/json; charset=utf-8' στις απαντήσεις API.
Ρυθμίστε τη βάση δεδομένων σας σε utf8mb4 (όχι μόνο utf8, που αποτελεί ένα 3-Byte subset). Ορίστε τη collation σύνδεσης σε utf8mb4_unicode_ci.
Επίλεξε γραμματοσειρές που να καλύπτουν τα στοχοθετικά σου συστήματα γραφής: Λατινικά, Κυριλλικά, CJK, Αραβικά, Ντεβαναγκάρι. Χρησιμοποίησε σύνολα γραμματοσειρών συστήματος ή Google Fonts με υποσύνολα γλωσσών για βέλτιστο φόρτωμα.
Έλεγξε την υλοποίηση i18n σου
Τεστ επέκτασης μήκους
Αύξησε όλα τα μεταφρασμένα κείμενα κατά 30-40% για να προσομοιώσεις την επέκταση κειμένου που συμβαίνει σε γλώσσες με πλουσιότερο λεξιλόγιο όπως τα Γερμανικά, τα Φινλανδικά ή τα Ελληνικά. Αυτό καλύπτει κοντέινερ με σταθερό πλάτος, κομμένα ετικέτες και υπερχείλιση κουμπιών προτού ξεκινήσεις τη μετάφραση. Πολλά εργαλεία ψευδο-τοπικοποίησης προσφέρουν αυτό ως ενσωματωμένο χαρακτηριστικό.
"Αποστολή" → "Ṡééééñðéñ_éxpáñðéð" (40% μακρύτερο)
Ψευδο-τοπικοποίηση
Ψευδο-τοπικοποίηση αντικαθιστά κάθε χαρακτήρα με ισοδύναμο με προσθήκη επικάλυψης (π.χ. 'a' → 'á') και περιβάλλει τα κείμενα με ετικέτες όπως [!! και !!]. Έτσι γίνεται άμεσα ορατό ποια strings είναι σκληρά κωδικοποιημένα και ποια προέρχονται από το σύστημα μετάφρασης. Εκτέλεσε Ψευδο-τοπικοποίηση ως μέρος της CI-ροής σου, για να ανιχνεύεις αυτόματα παλινδρομήσεις.
Κάθε κείμενο που εμφανίζεται στην οθόνη και δεν βρίσκεται εντός των [!! !!]-σημάνσεων είναι σκληροκωδικοποιημένο και πρέπει να εξωτερικευτεί. Αυτό το τεστ εντοπίζει το 95% των αγνοημένων συμβολοσειρών σε λιγότερο από ένα λεπτό.
"Αποστολή μηνύματος" → "[!! Ñáçḥŕíçḥṫ ṡéñðéñ !!]"
Δοκιμή διάταξης RTL
Ακόμη και χωρίς μεταφράσεις στα Αραβικά ή Εβραϊκά, μπορείς να δοκιμάσεις RTL διάταξη προσθέτοντας dir='rtl' στο ρίζας του HTML στοιχείου. Αυτό εντοπίζει άμεσα προβλήματα CSS κατεύθυνσης: λάθος ευθυγράμμιση εικονιδίων, margins στη λάθος πλευρά, χαλασμένη πλοήγηση και εσφαλμένη ταξινόμηση flex-items. Κάνε το ως βασικό έλεγχο σε κάθε sprint — χρειάζεται 10 δευτερόλεπτα για να αλλάξει και εντοπίζεις προβλήματα που αλλιώς θα απαιτούσαν εβδομάδες για να διορθωθούν στην παραγωγή.
Η λίστα ελέγχου i18n
['Όλες οι ορατές προς τον χρήστη συμβολοσειρές έχουν μεταφερθεί σε αρχεία πόρων', 'Δεν χρησιμοποιείται συνένωση συμβολοσειρών για τη δημιουργία προτάσεων', 'Έχουν υλοποιηθεί κανόνες πληθυντικού με ICU MessageFormat ή αντίστοιχο', 'Η μορφοποίηση ημερομηνιών, ωρών και αριθμών χρησιμοποιεί APIs προσαρμοσμένα ανά locale', 'Έχει δοκιμαστεί διάταξη RTL με αραβικά ή εβραϊκά περιεχόμενα', 'Ευέλικτο UI χωρίς σταθερό πλάτος σε στοιχεία που περιέχουν κείμενο', 'Έχει ρυθμιστεί γλώσσα fallback και ελέγχεται όταν λείπουν κλειδιά', 'Η κωδικοποίηση UTF-8 είναι συνεπής σε όλα τα αρχεία και βάσεις δεδομένων', 'Τα μεταδεδομένα App Store και Play Store προσαρμόζονται για κάθε αγορά', 'Στιγμιότυπα οθόνης και διαφημιστικά στοιχεία για κάθε γλώσσα ενημερώθηκαν']