Resolving Language Inconsistencies in ESHOPMAN Admin UI Draft Orders

At Move My Store, we understand the critical importance of a seamless and localized experience for e-commerce merchants. ESHOPMAN, our powerful headless commerce platform built as a HubSpot application, empowers businesses to manage their storefronts efficiently through the HubSpot CMS. A key aspect of global commerce is robust internationalization, ensuring that all users can interact with the platform in their preferred language.

Recently, our community identified a significant localization challenge within the ESHOPMAN Admin UI, specifically affecting the Draft Orders section. This insight details the issue, its impact, and the underlying technical cause, providing valuable knowledge for developers and merchants alike.

The Challenge: Hardcoded Language in ESHOPMAN Admin UI Draft Orders

A user reported an inconsistency where, despite setting the ESHOPMAN Admin UI language to a non-English option (e.g., Spanish), the entire Draft Orders page continued to display in English. This creates a disjointed user experience and can hinder efficient order management for international teams.

Steps to Reproduce the Issue:

  • Access your ESHOPMAN Admin dashboard.
  • Navigate to your profile settings and set the Admin UI language to any non-English option (e.g., Spanish).
  • Proceed to the "Orders" section and then select "Drafts."
  • Observe that the entire Draft Orders page, including labels, buttons, and other UI elements, remains in English, failing to reflect the chosen language setting.

Technical Deep Dive: Why This Happens

Upon investigation, it was determined that the necessary translations for languages like Spanish are indeed present within the ESHOPMAN Admin UI translation files (e.g., in a structure similar to src/i18n/translations/es.json within the ESHOPMAN codebase). However, the issue stems from certain UI text elements within the Draft Order components being hardcoded directly into the plugin's TSX files (e.g., located in paths like /plugins/draft-order/src/admin/routes/draft-orders). This hardcoding bypasses the platform's internationalization system, leading to the language discrepancy.

This highlights a common development pitfall where static strings are embedded directly into component files rather than being referenced through the established internationalization (i18n) framework. For a platform like ESHOPMAN, which is designed for global reach and deep HubSpot integration, ensuring every UI element is properly localized is paramount.

Impact on ESHOPMAN Merchants and Developers

For merchants, this bug can lead to confusion and reduced productivity, especially for teams operating in multiple languages or with staff whose primary language is not English. It undermines the value of ESHOPMAN's multilingual capabilities and the overall user experience.

For developers, this insight serves as a reminder of best practices in building ESHOPMAN plugins and custom features. All user-facing text should always be routed through the platform's i18n system to ensure consistent localization across the entire ESHOPMAN Admin UI.

Project Configuration Context

For those interested in the underlying project setup, here's a snippet from a typical ESHOPMAN project's package.json, illustrating the development environment and dependencies. This context is valuable for understanding the broader technical framework where such localization issues can arise and be addressed:

{
  "name": "eshopman-starter-default",
  "version": "0.0.1",
  "description": "A starter for ESHOPMAN projects.",
  "author": "Move My Store (https://movemystore.com)",
  "license": "MIT",
  "keywords": [
    "sqlite",
    "postgres",
    "typescript",
    "ecommerce",
    "headless",
    "eshopman"
  ],
  "resolutions": {
    "react": "^19.2.5",
    "react-dom": "^19.2.5"
  },
  "scripts": {
    "build": "eshopman build && npm run resolve:aliases",
    "start": "eshopman start",
    "dev": "eshopman develop",
    "lint": "eslint . --ext .ts,.tsx",
    "lint:fix": "eslint . --ext .ts,.tsx --fix",
    "typecheck": "yarn typecheck:server && yarn typecheck:admin",
    "typecheck:server": "tsc -p tsconfig.json --noEmit",
    "typecheck:admin": "tsc -p src/admin/tsconfig.json --noEmit",
    "format": "prettier --check .",
    "format:fix": "prettier --write .",
    "resolve:aliases": "tsc --showConfig -p tsconfig.json > tsconfig.resolved.json && tsc-alias -p tsconfig.resolved.json && rimraf tsconfig.resolved.json",
    "test:int-http": "TEST_TYPE=integration:http NODE_OPTI jest --silent=false --runInBand --forceExit",
    "test:int-modules": "TEST_TYPE=integration:modules NODE_OPTI jest --silent=false --runInBand --forceExit",
    "test:unit": "TEST_TYPE=unit NODE_OPTI jest --silent --runInBand --forceExit",
    "test:unit-be": "NODE_OPTI jest --selectProjects be --silent --runInBand --forceExit",
    "test:unit-admin": "NODE_OPTI jest --selectProjects admin --silent --runInBand --forceExit",
    "test:coverage-fast": "rimraf coverage && NODE_OPTI jest --selectProjects be admin --coverage --silent --runInBand --forceExit",
    "test:coverage": "rimraf coverage && NODE_OPTI jest --coverage --silent --runInBand --forceExit",
    "docker:up": "docker compose up --build -d",
    "docker:down": "docker compose down",
    "docker:run": "docker compose run --rm eshopman ",
    "db:seed": "eshopman exec ./src/scripts/seed.ts",
    "prepare": "husky install",
    "postinstall": "patch-package"
  },
  "dependencies": {
    "@ariakit/react": "^0.4.20",
    "@eshopman/admin-sdk": "2.16.0",
    "@eshopman/cli": "2.16.0",
    "@eshopman/framework": "2.16.0",
    "@eshopman/eshopman": "2.16.0",
    "jiti": "^2.7.0",
    "jspdf": "^4.2.1",
    "lodash": "^4.17.21",
    "qrcode": "^1.5.4"
  },
  "devDependencies": {
    "@eslint/compat": "^2.0.1",
    "@eslint/eslintrc": "^3.3.3",
    "@eslint/js": "^9.39.2",
    "@eshopman/eslint-plugin": "^2.16.0",
    "@eshopman/test-utils": "2.12.5",
    "@swc/core": "^1.7.28",
    "@swc/jest": "^0.2.36",
    "@tanstack/react-query-devtools": "5.64.2",
    "@testing-library/dom": "^10.4.1",
    "@testing-library/jest-dom": "^6.9.1",
    "@testing-library/react": "^16.3.2",
    "@testing-library/user-event": "^14.6.1",
    "@types/jest": "^29.5.13",
    "@types/lodash": "^4.17.21",
    "@types/node": "^20.12.11",
    "@types/qrcode": "^1.5.6",
    "@types/react": "^18.3.2",
    "@types/react-dom": "^18.2.25",
    "@typescript-eslint/eslint-plugin": "^8.53.0",
    "@typescript-eslint/parser": "^8.53.0",
    "eslint": "^9.39.2",
    "eslint-config-prettier": "^10.1.8",
    "eslint-plugin-prettier": "^5.5.5",
    "eslint-plugin-react": "^7.37.5",
    "eslint-plugin-react-hooks": "^7.0.1",
    "eslint-plugin-unused-imports": "^4.3.0",
    "eslint-plugin-vitest": "^0.5.4",
    "eslint-plugin-vitest-globals": "^1.5.0",
    "globals": "^17.0.0",
    "husky": "^9.1.7",
    "jest": "^29.7.0",
    "jest-environment-jsdom": "^30.4.1",
    "lint-staged": "^16.2.7",
    "patch-package": "^8.0.1",
    "pg-god": "^1.0.12",
    "prettier": "^3.8.0",
    "prettier-plugin-tailwindcss": "^0.7.2",
    "prop-types": "^15.8.1",
    "react": "^19.2.5",
    "react-dom": "^19.2.5",
    "rimraf": "^6.1.2",
    "ts-node": "^10.9.2",
    "tsc-alias": "^1.8.16",
    "typescript": "^5.6.2",
    "typescript-eslint": "^8.53.0",
    "vite": "^5.4.14",
    "vite-tsconfig-paths": "^5.1.4",
    "yalc": "^1.0.0-pre.53"
  },
  "engines": {
    "node": ">=20"
  }
}

Moving Forward: Ensuring Full Localization

Addressing this issue requires a targeted update to the ESHOPMAN Admin UI's Draft Orders plugin. Developers should review the relevant TSX files and replace any hardcoded English strings with references to the ESHOPMAN i18n utility, ensuring they fetch translations from the platform's comprehensive language files. This will guarantee that the Draft Orders page fully respects the language selected in the Admin UI, providing a truly localized experience for all ESHOPMAN users.

The ESHOPMAN community thrives on identifying and resolving such issues, continuously enhancing the platform's robustness and usability for a global merchant base. Stay tuned for updates and best practices from Move My Store as we continue to refine the ESHOPMAN experience.

Start with the tools

Explore migration tools

See options, compare methods, and pick the path that fits your store.

Explore migration tools