diff --git a/locales/de/translation.json b/locales/de/translation.json
index 24efd75037d4a9192960d1da5e26a371b7a93895..3f2933b16e46259186f12a8c6a81b8ba6b091402 100644
--- a/locales/de/translation.json
+++ b/locales/de/translation.json
@@ -2,10 +2,10 @@
   "translation": {
     "aboutThisItem": "Über dieses Element",
     "add": "Hinzufügen",
+    "addedFromUrl": "(via URL hinzugefügt)",
     "addManifestUrl": "Ort der Ressource",
     "addManifestUrlHelp": "Die URL einer IIIF-Ressource",
     "addResource": "Ressource hinzufügen",
-    "addedFromUrl": "(via URL hinzugefügt)",
     "annotations": "Annotationen",
     "book": "Buch",
     "bottom": "Unten",
@@ -13,9 +13,9 @@
     "canvasIndex": "Index",
     "closeAddResourceMenu": "Resourcenliste schließen",
     "closeAnnotationCompanionWindow": "Annotationsfenster schließen",
+    "closeCanvasNavigationCompanionWindow": "Hilfsfenster für die Leinwandnavigation schließen",
     "closeCompanionWindow": "Hilfsfenster schließen",
     "closeInfoCompanionWindow": "Informationshilfsfenster schließen",
-    "closeCanvasNavigationCompanionWindow": "Hilfsfenster für die Leinwandnavigation schließen",
     "closeWindow": "Fenster schließen",
     "closeWindowMenu": "Fenstermenü schließen",
     "currentItem": "Objekt",
@@ -37,22 +37,22 @@
     "numItems": "{{number}} Elemente",
     "off": "Keine",
     "openAnnotationCompanionWindow": "Annotationsfenster öffnen",
-    "openInfoCompanionWindow": "Informationshilfsfenster",
     "openCanvasNavigationCompanionWindow": "Hilfsfenster für die Leinwandnavigation schließen",
-    "openWindows": "Fenster öffnen",
     "openInCompanionWindow": "In Hilfsfenster öffnen",
+    "openInfoCompanionWindow": "Informationshilfsfenster",
+    "openWindows": "Fenster öffnen",
     "position": "Position",
     "previewWindowTitle": "Mirador",
     "previousCanvas": "Vorherigen Objekt",
     "resource": "Ressource",
     "right": "Rechts",
-    "single": "Einzeln",
     "settings": "Einstellungen",
-    "showZoomControls": "Zoomsteuerung anzeigen",
     "showingNumAnnotations": "{{number}} Annotationen werden angezeigt",
+    "showZoomControls": "Zoomsteuerung anzeigen",
+    "single": "Einzeln",
     "theme": "Farbschema",
-    "thumbnails": "Miniaturansicht",
     "thumbnailNavigation": "Miniaturansicht",
+    "thumbnails": "Miniaturansicht",
     "toggleWindowSideBar": "Seitenleiste umschalten",
     "tryAgain": "Wiederholen",
     "untitled": "[Unbenannt]",
diff --git a/locales/en/translation.json b/locales/en/translation.json
index e4a3d5451b5047146e7b03bcb5bc4396e922a8f1..a926afd4463fa86adb58cd49798dff8364fcfaec 100644
--- a/locales/en/translation.json
+++ b/locales/en/translation.json
@@ -2,10 +2,10 @@
   "translation": {
     "aboutThisItem": "About this item",
     "add": "Add",
+    "addedFromUrl": "(Added from URL)",
     "addManifestUrl": "Resource location",
     "addManifestUrlHelp": "The URL of a IIIF resource",
     "addResource": "Add resource",
-    "addedFromUrl": "(Added from URL)",
     "annotations": "Annotations",
     "book": "Book",
     "bottom": "Bottom",
@@ -13,9 +13,9 @@
     "canvasIndex": "Index",
     "closeAddResourceMenu": "Close add resource panel",
     "closeAnnotationCompanionWindow": "Close annotation companion window",
+    "closeCanvasNavigationCompanionWindow": "Close canvas navigation companion window",
     "closeCompanionWindow": "Close this companion window",
     "closeInfoCompanionWindow": "Close information companion window",
-    "closeCanvasNavigationCompanionWindow": "Close canvas navigation companion window",
     "closeWindow": "Close window",
     "closeWindowMenu": "Close window options menu",
     "currentItem": "Current item",
@@ -32,31 +32,31 @@
     "light": "Light",
     "listAllOpenWindows": "List all open windows",
     "manifestError": "The resource cannot be added:",
+    "menu": "Menu",
     "miradorResources": "Mirador resources",
     "miradorViewer": "Mirador viewer",
-    "nextCanvas": "Next item",
-    "menu": "Menu",
     "mosaic": "Mosaic",
+    "nextCanvas": "Next item",
     "numItems": "{{number}} items",
     "off": "Off",
     "openAnnotationCompanionWindow": "Open annotation companion window",
-    "openInfoCompanionWindow": "Open information companion window",
     "openCanvasNavigationCompanionWindow": "Open canvas navigation companion window",
-    "openWindows": "Open windows",
     "openInCompanionWindow": "Open in companion window",
+    "openInfoCompanionWindow": "Open information companion window",
+    "openWindows": "Open windows",
     "position": "Position",
     "previewWindowTitle": "Mirador",
     "previousCanvas": "Previous item",
     "resource": "Resource",
     "right": "Right",
-    "single": "Single",
+    "selectWorkspaceMenu": "Select workspace type",
     "settings": "Settings",
-    "showZoomControls": "Show Zoom Controls",
     "showingNumAnnotations": "Showing {{number}} annotations",
-    "selectWorkspaceMenu": "Select workspace type",
+    "showZoomControls": "Show Zoom Controls",
+    "single": "Single",
     "theme": "Theme",
-    "thumbnails": "Thumbnails",
     "thumbnailNavigation": "Thumbnail carousel",
+    "thumbnails": "Thumbnails",
     "toggleWindowSideBar": "Toggle window sidebar",
     "tryAgain": "Try again",
     "untitled": "[Untitled]",
@@ -64,10 +64,9 @@
     "window": "Window: {{label}}",
     "windowMenu": "Window menu",
     "workspace": "Workspace",
-    "workspaceMenu": "Workspace menu",
     "workspaceFullScreen": "Full Screen",
+    "workspaceMenu": "Workspace menu",
     "workspaceSelectionTitle": "Select a workspace type",
-    "workspace": "Workspace",
     "zoomIn": "Zoom in",
     "zoomOut": "Zoom out",
     "zoomReset": "Reset zoom"
diff --git a/package.json b/package.json
index 26bbfe63c2e506eb838cbcb4e2a177687a9997b3..96013af403b7eb39db645b75c96c5aceb2a7fe68 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,7 @@
     "dist"
   ],
   "scripts": {
-    "lint": "node_modules/.bin/eslint ./ && node_modules/.bin/sass-lint -v ./src/styles/**/*",
+    "lint": "node_modules/.bin/eslint ./ && node_modules/.bin/sass-lint -v ./src/styles/**/* && node ./scripts/i18n-lint.js",
     "server": "node_modules/.bin/http-server",
     "test": "npm run build && npm run lint && npm run size && jest -c jest.json",
     "test:watch": "jest -c jest.json --watch",
@@ -71,6 +71,7 @@
     "babel-eslint": "10.0.1",
     "babel-jest": "^24.1.0",
     "babel-loader": "^8.0.4",
+    "chalk": "^2.4.2",
     "codecov": "^3.1.0",
     "concurrently": "^4.0.1",
     "css-loader": "^2.1.0",
@@ -85,6 +86,7 @@
     "eslint-plugin-jest": "^22.2.2",
     "eslint-plugin-jsx-a11y": "^6.2.0",
     "eslint-plugin-react": "^7.12.4",
+    "glob": "^7.1.3",
     "http-server": "^0.11.1",
     "jest": "^24.1.0",
     "jest-fetch-mock": "^2.1.1",
diff --git a/scripts/i18n-lint.js b/scripts/i18n-lint.js
new file mode 100644
index 0000000000000000000000000000000000000000..946189fa476c934958e06579c4f1363c91e27b1c
--- /dev/null
+++ b/scripts/i18n-lint.js
@@ -0,0 +1,73 @@
+const glob = require('glob'); // eslint-disable-line import/no-extraneous-dependencies
+const fs = require('fs');
+const chalk = require('chalk'); // eslint-disable-line import/no-extraneous-dependencies
+
+const { log } = console;
+const globOpts = { cwd: 'locales' };
+const defaultLocaleFile = 'en/translation.json';
+const files = glob.sync('**/translation.json', globOpts);
+const normalizedFiles = {};
+const errors = {};
+
+/**
+ * Return a new copy of the array lowercased and sorted
+ */
+function lowerCaseSortedArray(arr) {
+  return arr.slice().map(v => v.toLowerCase()).sort();
+}
+
+/**
+ * Return the keys in an array that are not sorted (not considering case in sort)
+ */
+function unsortedKeys(arr) {
+  const sortedArray = lowerCaseSortedArray(arr);
+
+  return arr.filter((v, i) => v.toLowerCase() !== sortedArray[i]);
+}
+
+/**
+ * Return any keys in array 2 that are not in array 1
+ * (values will be sorted and downcased for comparison)
+ */
+function missingKeys(arr1, arr2) {
+  const sortedDonwcasedLeftHandArray = lowerCaseSortedArray(arr1);
+  const sortedDonwcasedRightHandArray = lowerCaseSortedArray(arr2);
+
+  return sortedDonwcasedLeftHandArray.filter((v, i) => v !== sortedDonwcasedRightHandArray[i]);
+}
+
+files.forEach((fileName) => {
+  const fileContent = fs.readFileSync(`locales/${fileName}`);
+  normalizedFiles[fileName] = Object.keys(JSON.parse(fileContent.toString()).translation);
+});
+
+const completeKeys = normalizedFiles[defaultLocaleFile].slice().sort();
+
+
+Object.keys(normalizedFiles).forEach((fileName) => {
+  const unsorted = unsortedKeys(normalizedFiles[fileName]);
+  const missing = missingKeys(completeKeys, normalizedFiles[fileName]);
+
+  if (unsorted.length) {
+    errors[fileName] = errors[fileName] || [];
+    errors[fileName].push('Keys are not sorted properly');
+    errors[fileName].push(
+      `\tSorting starts to be incorrect around: ${unsorted[0]}`,
+    );
+  }
+
+  if (missing.length) {
+    errors[fileName] = errors[fileName] || [];
+    errors[fileName].push('Some keys from the default locale file are missing');
+    errors[fileName].push(
+      `\tMissing keys: ${missing.join(', ')}`,
+    );
+  }
+});
+
+Object.keys(errors).forEach((errorFileName) => {
+  log(chalk.red(`${chalk.inverse.bold(errorFileName)} has ${chalk.underline.bold('internationalization')} errors`));
+  errors[errorFileName].forEach((error) => {
+    log(`\t${chalk.yellow(error)}`);
+  });
+});