
Security News
Risky Biz Podcast: Making Reachability Analysis Work in Real-World Codebases
This episode explores the hard problem of reachability analysis, from static analysis limits to handling dynamic languages and massive dependency trees.
jamstack-translate
Advanced tools
Google Translate your source folder and compile to static dist language directories without writing convoluted references to json files... I hate i18n libraries so much, here is my personal fix.
<t>Some String</t>
.
├── src
| └── components
| | └── Header.svelte
| | └── NoTranslations.svelte
| └── helpers.js
| └── App.svelte
| └── main.js
<!-- ./src/components/Header.svelte -->
<header>
<t>Welcome</t>
</header>
// ./src/helpers.js
const string = `<t>Welcome to ${name}</t>`
.
├── src
| ├── __generated__
| | └── es
| | | └── components
| | | | └── Header.svelte
| | | | └── NoTranslations.svelte
| | | └── helpers.js
| | | └── App.svelte
| | └── fr
| | | └── components
| | | | └── Header.svelte
| | | | └── NoTranslations.svelte
| | | └── helpers.js
| | | └── App.svelte
| └── components
| | └── Header.svelte
| | └── NoTranslations.js
| └── helpers.js
| └── App.svelte
| └── main.js
<!-- ./src/__generated__/fr/components/Header.svelte -->
<header>
<t>Bienvenue</t>
</header>
// ./src/__generated__/fr/helpers.js
const string = `<t>Bienvenue sur ${name}</t>`
The package also produces a (specified) JSON file with your translations, so you may load from file, adjusting translations after initial run.
[
{
"_src": "./src/components/Header.svelte",
"en": "Welcome",
"es": "Bienvenidos",
"fr": "Bienvenue"
},
{
"_src": "./src/helpers.js",
"en": "Welcome to ${name}",
"es": "Bienvenido a ${name}",
"fr": "Bienvenue sur ${name}"
},
]
This file allows version control of your translations, also allows easy A/B testing for your translations quite easily.
See the Example Svelte.js or Example Vue.js for how your project can look.
npm install --save-dev jamstack-translate
Create a file in your root directory (ex: translate.js)
require('dotenv').config()
const translate = require('../index.js');
const GOOGLEKEY = process.env.GOOGLE_API_KEY
const OPTIONS = {
targetLanguages: [
'fr',
'es',
],
targetFiles: [
'./src/App.svelte',
'./src/components/**/*.svelte',
'./src/views/**/*.svelte',
'./src/helpers.js',
// etc
],
targetDirectory: './src/__generated__/',
sourceDirectory: './src/',
translationFile: './translations.json',
loadTranslationsFromFile: true,
}
const init = async () => {
const result = await translate(GOOGLEKEY, OPTIONS);
console.log(result);
}
init();
then simply run
node translate.js
The pacakge does some rudimentary regex/replace in order to address most issues (mostly caused by Google translate), here are those issues currenlty active and observed.
For most issues, you can manually fix these issues in your created JSON file, and compile with fixes.
Currently, this...
<t><span class="text--green">hello</span> there</t>
Becomes...
<t><span class="text - green"> bonjour </span> là</t>
Currently, if you translate a string inside a JS file, like so...
const string = '<t>Please</t>'
Becomes
const string = '<t>S'il vous plaît</t>'
Which is unnescaped, and will cause and compile/runtime error.
Best to use backticks instead of single quotes.
const string = `<t>Please</t>`
If you can't use backticks, you must manually escape the single quotes created in your created JSON file, and compile with fixes.
[
{
_file: "file.html",
en: "Please",
fr: "S\\'il vous plaît"
}
]
For every new language folder you create, create a new entry file (multi input) for your application and point the respective imports to their lanuage folder. Then, in your index.html
file, dynamically load your bundle.js
depending on your method of choosing languages (I prefer URL parameters ?lng={language}
).
Note: Below is with Rollup/Svelte v3, other docs for webpack etc. will coming soon.
Create new main.js files for each new langauge,
.
├── src
| └── App.svelte
| └── main-es.js <<<< New
| └── main-fr.js <<<< New
| └── main.js
Edit each new main file, and point to your new entry file
main-fr.js
import App from './__generated__/fr/App.svelte';
const app = new App({
target: document.body,
props: {
name: 'world'
}
});
export default app;
Generate a new bundle for each main file
Rollup.config.js
//...
import multiInput from 'rollup-plugin-multi-input';
export default {
input: [{
bundle_en: 'src/main.js',
bundle_fr: 'src/main-fr.js',
bundle_es: 'src/main-es.js',
}],
output: {
sourcemap: true,
name: 'app',
format: 'es',
dir: 'public/build'
},
plugins: [
multiInput(),
// ...
In your HTML, instead of a script tag for bundle.js, dynamically load your new bundle depending on query param ?lng={language}
<!-- <script defer src='/build/bundle.js'></script> -->
<script>
var urlParams = new URLSearchParams(window.location.search);
var language = urlParams.get('lng') || 'en';
language = language.toLowerCase()
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'module';
script.src = '/build/bundle_' + language + '.js';
head.appendChild(script);
</script>
And then use like so:
http://localhost:5000/?lng=es
index.html
=> fr/index.html
)src/
to src/__generated__/${lang}/
src/__generated__/${lang}/
with their translations.__generated__
folder, and language folders inside.dist
.<title>
translations, as this is parsed as a string inside the html. Do replace?{name}
becomes {nombre}
etc.
<t>Hello ___{name}___</t>
=> <t>Hola {name}</t>
FAQs
Generate static translations for any front end project.
We found that jamstack-translate demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
This episode explores the hard problem of reachability analysis, from static analysis limits to handling dynamic languages and massive dependency trees.
Security News
/Research
Malicious Nx npm versions stole secrets and wallet info using AI CLI tools; Socket’s AI scanner detected the supply chain attack and flagged the malware.
Security News
CISA’s 2025 draft SBOM guidance adds new fields like hashes, licenses, and tool metadata to make software inventories more actionable.