-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add page for missing translation strings #127
Comments
not sure if this is something for the frontend. As far as a know, you can show the missing translations if you were on a page where such missing translation appears, so if you do not visit every page in every variation, you will not get all missing translation strings. another solution would be maintaining another file, which stores all translation keys and compare it to the actual ones. Also not really handy... For now comparing the number of lines gives a good hint if something is missing (even there are currently some differences between all files in size of 1 line) Can i create a page where all translations string are shown which are missing? ChatGPT: Here’s how you can achieve that: Approach 1: Using i18next missingKeyHandler Step-by-Step Guide:
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
const missingTranslations = []; // Array to store missing keys
i18n
.use(initReactI18next) // Bind react-i18next to the instance
.init({
resources: {
en: {
translation: {
"welcome": "Welcome to the app!",
// Add your translations here
}
},
fr: {
translation: {
"welcome": "Bienvenue dans l'application!",
// Add your translations here
}
}
},
lng: 'en', // Default language
fallbackLng: 'en', // Fallback language if key is missing
debug: true, // Enable debug mode to track missing translations
saveMissing: true, // Enable saving missing translations
missingKeyHandler: (lng, ns, key, fallbackValue) => {
console.warn(`Missing translation for ${key} in ${lng}`);
if (!missingTranslations.includes(key)) {
missingTranslations.push(key); // Add missing key to the array
}
},
interpolation: {
escapeValue: false, // React already handles XSS
}
});
export { missingTranslations }; // Export the missing translations array
export default i18n;
import React from 'react';
import { missingTranslations } from './i18n';
const MissingTranslationsPage = () => {
return (
<div>
<h1>Missing Translations</h1>
{missingTranslations.length > 0 ? (
<ul>
{missingTranslations.map((key, index) => (
<li key={index}>{key}</li>
))}
</ul>
) : (
<p>All translations are available!</p>
)}
</div>
);
};
export default MissingTranslationsPage;
Code kopieren
import React from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import MissingTranslationsPage from './MissingTranslationsPage';
import HomePage from './HomePage'; // Example of another page
const App = () => {
return (
<Router>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/missing-translations" element={<MissingTranslationsPage />} />
</Routes>
</Router>
);
};
export default App;
Approach 2: Manually Check Missing Translations
Code kopieren
export const translationKeys = [
'welcome',
'greeting',
'goodbye',
// Add all keys here
];
Code kopieren
import React from 'react';
import i18n from './i18n'; // Import your i18n configuration
import { translationKeys } from './translationKeys'; // Import all defined keys
const MissingTranslationsPage = () => {
const missingKeys = [];
// Check for missing translations in the current language
translationKeys.forEach((key) => {
if (!i18n.exists(key)) {
missingKeys.push(key);
}
});
return (
<div>
<h1>Missing Translations</h1>
{missingKeys.length > 0 ? (
<ul>
{missingKeys.map((key, index) => (
<li key={index}>{key}</li>
))}
</ul>
) : (
<p>All translations are available!</p>
)}
</div>
);
};
export default MissingTranslationsPage; Explanation: Approach 2 compares all your translation keys at once against the existing translations. It requires you to maintain a list of all translation keys (translationKeys.js), but it can show all the missing keys at once without needing to interact with the app. Conclusion Let me know which approach works best for your use case! |
The idea I have in mind would be: Expect the English translation is complete and compare it with the other ones, including non used strings. |
ok. then chatGPT proposes a solution. will test that: To implement this translation comparison logic within a React page, you can use a similar approach as the script I described but move the logic into a React component. This component can display the missing and extra keys in the browser. Here’s a step-by-step guide on how to create a React page that compares the translation JSON files and shows missing and extra keys dynamically: Step 1: Organize Your Translation Files public/ These will be fetched dynamically within the React app. Step 2: Create the React Component import React, { useEffect, useState } from 'react';
// Recursive function to find missing keys
const findMissingKeys = (baseObj, otherObj, parentKey = '') => {
const missingKeys = [];
Object.keys(baseObj).forEach((key) => {
const fullKey = parentKey ? `${parentKey}.${key}` : key;
if (typeof baseObj[key] === 'object' && !Array.isArray(baseObj[key])) {
missingKeys.push(...findMissingKeys(baseObj[key], otherObj[key] || {}, fullKey));
} else if (!(key in otherObj)) {
missingKeys.push(fullKey);
}
});
return missingKeys;
};
// Recursive function to find extra keys
const findExtraKeys = (baseObj, otherObj, parentKey = '') => {
const extraKeys = [];
Object.keys(otherObj).forEach((key) => {
const fullKey = parentKey ? `${parentKey}.${key}` : key;
if (typeof otherObj[key] === 'object' && !Array.isArray(otherObj[key])) {
extraKeys.push(...findExtraKeys(baseObj[key] || {}, otherObj[key], fullKey));
} else if (!(key in baseObj)) {
extraKeys.push(fullKey);
}
});
return extraKeys;
};
const TranslationComparison = () => {
const [translations, setTranslations] = useState({});
const [missingKeys, setMissingKeys] = useState({});
const [extraKeys, setExtraKeys] = useState({});
const [loading, setLoading] = useState(true);
const languages = ['en', 'fr', 'de', 'es']; // Add other languages as needed
const baseLang = 'en'; // Base language to compare against
useEffect(() => {
// Fetch all translation files
const fetchTranslations = async () => {
const fetchedTranslations = {};
for (let lang of languages) {
const response = await fetch(`/translations/${lang}.json`);
const data = await response.json();
fetchedTranslations[lang] = data;
}
setTranslations(fetchedTranslations);
setLoading(false);
};
fetchTranslations();
}, []);
useEffect(() => {
if (!loading && translations[baseLang]) {
const baseTranslations = translations[baseLang];
const missing = {};
const extra = {};
// Compare each language against the base language
languages.forEach((lang) => {
if (lang !== baseLang) {
const otherTranslations = translations[lang];
missing[lang] = findMissingKeys(baseTranslations, otherTranslations);
extra[lang] = findExtraKeys(baseTranslations, otherTranslations);
}
});
setMissingKeys(missing);
setExtraKeys(extra);
}
}, [loading, translations]);
if (loading) return <p>Loading translations...</p>;
return (
<div>
<h1>Translation Comparison</h1>
{languages.map((lang) => (
lang !== baseLang && (
<div key={lang}>
<h2>Language: {lang.toUpperCase()}</h2>
<h3>Missing Keys:</h3>
{missingKeys[lang]?.length > 0 ? (
<ul>
{missingKeys[lang].map((key, index) => (
<li key={index}>{key}</li>
))}
</ul>
) : (
<p>No missing keys.</p>
)}
<h3>Extra Keys:</h3>
{extraKeys[lang]?.length > 0 ? (
<ul>
{extraKeys[lang].map((key, index) => (
<li key={index}>{key}</li>
))}
</ul>
) : (
<p>No extra keys.</p>
)}
</div>
)
))}
</div>
);
};
export default TranslationComparison; Step 3: Explanation In the useEffect hook, the component fetches the translation files for each language from the /locales folder using fetch. Once all the translation files are fetched, the code compares the translations using the recursive findMissingKeys and findExtraKeys functions. For each language other than the base language, the component displays the list of missing and extra keys. If no missing or extra keys are found, a message like "No missing keys" or "No extra keys" is shown. import React from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import TranslationComparison from './TranslationComparison';
function App() {
return (
<Router>
<Routes>
<Route path="/translation-comparison" element={<TranslationComparison />} />
{/* Other routes */}
</Routes>
</Router>
);
}
export default App; Step 5: Testing Let me know if you need any additional details! |
It may be helpful to have a page that shows missing translation-strings, like the one with the missing tonie information.
The text was updated successfully, but these errors were encountered: