Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to extract all string constants from HTML or JSX?

EDIT: I ended up making a babel plugin CLI tool myself called i18nize-react :D


I am trying to translate an existing react app from English to another language. All the string constants in the JSX are hard coded. Is there an easy way to extract all the string constants and dump them in a .json file?

Here is an example of what I am trying to do.

// Original js file
class Component1 extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      // ...
    }
  }

  render(){
    return(
      <div>
        Some Text
        <p>
          Some more text
          <a href="/some/route">
            Some link
          </a>
        </p>
      </div>
    )
  }
}

STRINGS.json

{
  "ENGLISH":{
    "TEXT1":"Some Text",
    "TEXT2":"Some more text",
    "TEXT3":"Some link"
  },
  "OTHER_LANGUAGE":{
    "TEXT1":"asfsadfasfd",
    "TEXT2":"sadfsfd",
    "TEXT3":"sdfsdfsfdfd"
  }
}

New component

// After the strings are extracted
import STRINGS from strings.json

class Component1 extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      // ...
    }
  }

  render(){
    return(
      <div>
        {STRINGS[this.props.language].TEXT1}
        <p>
          {STRINGS[this.props.language].TEXT2}
          <a href="/some/route">
            {STRINGS[this.props.language].TEXT3}
          </a>
        </p>
      </div>
    )
  }
}
like image 951
Souradeep Nanda Avatar asked Sep 14 '25 23:09

Souradeep Nanda


1 Answers

You're going to want to use a javascript abstract syntax tree parser. A popular one is acorn, another one is espree. If you're using acorn, you'll want the acorn-jsx plugin

Here's an example that spits out the JSON files you want (although it does it for every function. If you wanted to be more specific, you could scope it to the render function):

const fs = require('fs');
const acorn = require('acorn-jsx-walk');
const walk = acorn.default;
const { MethodDefinition, Literal } = acorn.base;

const file = fs.readFileSync('./file.js', 'utf8');

const strings = [];

walk(file, {
  Literal({ value }) {
    strings.push(value.trim());
  }
});

const ENGLISH = strings.reduce((acc, item, i) => {
  acc[`TEXT${i+1}`] = item;
  return acc;
}, {});

console.log(JSON.stringify({ ENGLISH }, null, 2));

returns:

{
  "ENGLISH": {
    "TEXT1": "Some Text",
    "TEXT2": "Some more text",
    "TEXT3": "Some link",
    "TEXT4": "",
    "TEXT5": ""
  }
}

Creating a new javascript file is more complicated, but it would involve adding logic around the AST and then re-generating the javascript file from it. (It's probably worth a separate question once you pick the tools you're going to use)

like image 153
AnilRedshift Avatar answered Sep 17 '25 14:09

AnilRedshift