[Loc] Migrate ui to Localization V2

- Migrate ui to use Localization V2 APIs.
- Migrate ui/components to use Localization V2 APIs.
- Removed ui grdps
- Removed ui/components grdps

Tested with en-XL.json
https://imgur.com/KOs5bka
https://imgur.com/OdiQElI

Bug: 1136655
Change-Id: I9b2456d8eb4e6dff3624ae688896bee014ea3579
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2698380
Commit-Queue: Vidal Diazleal <[email protected]>
Reviewed-by: Simon Zünd <[email protected]>
diff --git a/front_end/common/common_strings.grdp b/front_end/common/common_strings.grdp
index 81b7eb3..8dfbfbe 100644
--- a/front_end/common/common_strings.grdp
+++ b/front_end/common/common_strings.grdp
@@ -36,6 +36,9 @@
   <message name="IDS_DEVTOOLS_45edc1b96407d9d213dd1135962a32a0" desc="Name of a network resource type">
     WebSocket
   </message>
+  <message name="IDS_DEVTOOLS_4789f23283b3a61f858b641a1bef19a3" desc="Text for the memory of the page">
+    Memory
+  </message>
   <message name="IDS_DEVTOOLS_4cafcd8bd18c79335c2484f1750ce3dd" desc="Name of a network initiator type">
     Preflight
   </message>
@@ -72,18 +75,30 @@
   <message name="IDS_DEVTOOLS_8cf6dd5e7b4fe7b6df3319b9803278f3" desc="Name of a network resource type">
     EventSource
   </message>
+  <message name="IDS_DEVTOOLS_9446a98ad14416153cc4d45ab8b531bf" desc="Text for the performance of something">
+    Performance
+  </message>
   <message name="IDS_DEVTOOLS_a1c58e94227389415de133efdf78ea6e" desc="Text for DevTools appearance">
     Appearance
   </message>
   <message name="IDS_DEVTOOLS_a83f1ca5ad00b39773d9e6a26b0e70b2" desc="Text that appears in a tooltip for the JavaScript types filter.">
     Scripts
   </message>
+  <message name="IDS_DEVTOOLS_aa56a2e65d8106aef3c61e4f6bf94fdb" desc="Title of the Elements Panel">
+    Elements
+  </message>
   <message name="IDS_DEVTOOLS_b5dc9b0e6beecb1e80f6f1b5b3050f12" desc="The UI destination when right clicking an item that can be revealed">
     Application panel
   </message>
   <message name="IDS_DEVTOOLS_b85815d04cec053ce6deb8021f2df1b8" desc="Name of a network resource type">
     Ping
   </message>
+  <message name="IDS_DEVTOOLS_b94d8a074eddd267702810179875737f" desc="Text that refers to the debugger">
+    Debugger
+  </message>
+  <message name="IDS_DEVTOOLS_bccaa4aa80831b76c11240a16447975f" desc="Title of the Console tool">
+    Console
+  </message>
   <message name="IDS_DEVTOOLS_be53a0541a6d36f6ecb879fa2c584b08" desc="Text in Image View of the Sources panel">
     Image
   </message>
@@ -111,9 +126,15 @@
   <message name="IDS_DEVTOOLS_ee02b74d0caebce3dabaf3b3e79b6a65" desc="The UI destination when right clicking an item that can be revealed">
     Issues view
   </message>
+  <message name="IDS_DEVTOOLS_eec89088ee408b80387155272b113256" desc="Title of the Network tool">
+    Network
+  </message>
   <message name="IDS_DEVTOOLS_f28128b38efbc6134dc40751ee21fd29" desc="Text for documents, a type of resources">
     Documents
   </message>
+  <message name="IDS_DEVTOOLS_fb61758d0f0fda4ba867c3d5a46c16a7" desc="Name of the Sources panel">
+    Sources
+  </message>
   <message name="IDS_DEVTOOLS_fff0d600f8a0b5e19e88bfb821dd1157" desc="Text that appears in a tooltip for the image types filter.">
     Images
   </message>
diff --git a/front_end/emulation/emulation_strings.grdp b/front_end/emulation/emulation_strings.grdp
index eb7d064..74ccfca 100644
--- a/front_end/emulation/emulation_strings.grdp
+++ b/front_end/emulation/emulation_strings.grdp
@@ -315,6 +315,9 @@
   <message name="IDS_DEVTOOLS_abbd64f40c34c537d3a571af068fce29" desc="Text for the orientation of something">
     Orientation
   </message>
+  <message name="IDS_DEVTOOLS_af29aa178ae43211319e28f627e96590" desc="Title of an action in the emulation tool to show sensors">
+    Sensors
+  </message>
   <message name="IDS_DEVTOOLS_ba4ff28193ef85288d9658df2a6f6138" desc="Error message in the Device settings pane that shows that the entered brands list has wrong syntax">
     Brands list is not a valid structured fields list.
   </message>
diff --git a/front_end/i18n/locales/en-US.json b/front_end/i18n/locales/en-US.json
index c9136fd..ae68272 100644
--- a/front_end/i18n/locales/en-US.json
+++ b/front_end/i18n/locales/en-US.json
@@ -9431,6 +9431,246 @@
   "timeline/UIDevtoolsUtils.js | system": {
     "message": "System"
   },
+  "ui/components/DataGrid.ts | headerOptions": {
+    "message": "Header Options"
+  },
+  "ui/components/DataGrid.ts | resetColumns": {
+    "message": "Reset Columns"
+  },
+  "ui/components/DataGrid.ts | sortBy": {
+    "message": "Sort By"
+  },
+  "ui/components/SurveyLink.ts | anErrorOccurredWithTheSurvey": {
+    "message": "An error occurred with the survey"
+  },
+  "ui/components/SurveyLink.ts | openingSurvey": {
+    "message": "Opening survey …"
+  },
+  "ui/components/SurveyLink.ts | thankYouForYourFeedback": {
+    "message": "Thank you for your feedback"
+  },
+  "ui/DockController.js | close": {
+    "message": "Close"
+  },
+  "ui/DockController.js | dockToBottom": {
+    "message": "Dock to bottom"
+  },
+  "ui/DockController.js | dockToLeft": {
+    "message": "Dock to left"
+  },
+  "ui/DockController.js | dockToRight": {
+    "message": "Dock to right"
+  },
+  "ui/DockController.js | undockIntoSeparateWindow": {
+    "message": "Undock into separate window"
+  },
+  "ui/EmptyWidget.js | learnMore": {
+    "message": "Learn more"
+  },
+  "ui/FilterBar.js | allStrings": {
+    "message": "All"
+  },
+  "ui/FilterBar.js | egSmalldUrlacomb": {
+    "message": "e.g. /small[d]+/ url:a.com/b"
+  },
+  "ui/FilterBar.js | filter": {
+    "message": "Filter"
+  },
+  "ui/FilterBar.js | sclickToSelectMultipleTypes": {
+    "message": "{PH1}Click to select multiple types"
+  },
+  "ui/Infobar.js | close": {
+    "message": "Close"
+  },
+  "ui/Infobar.js | dontShowAgain": {
+    "message": "Don't show again"
+  },
+  "ui/Infobar.js | learnMore": {
+    "message": "Learn more"
+  },
+  "ui/InspectorView.js | closeDrawer": {
+    "message": "Close drawer"
+  },
+  "ui/InspectorView.js | moreTools": {
+    "message": "More Tools"
+  },
+  "ui/InspectorView.js | moveToBottom": {
+    "message": "Move to bottom"
+  },
+  "ui/InspectorView.js | moveToTop": {
+    "message": "Move to top"
+  },
+  "ui/InspectorView.js | panels": {
+    "message": "Panels"
+  },
+  "ui/InspectorView.js | reloadDevtools": {
+    "message": "Reload DevTools"
+  },
+  "ui/ListWidget.js | addString": {
+    "message": "Add"
+  },
+  "ui/ListWidget.js | cancelString": {
+    "message": "Cancel"
+  },
+  "ui/ListWidget.js | editString": {
+    "message": "Edit"
+  },
+  "ui/ListWidget.js | removeString": {
+    "message": "Remove"
+  },
+  "ui/ListWidget.js | saveString": {
+    "message": "Save"
+  },
+  "ui/RemoteDebuggingTerminatedScreen.js | reconnectDevtools": {
+    "message": "Reconnect DevTools"
+  },
+  "ui/RemoteDebuggingTerminatedScreen.js | reconnectWhenReadyByReopening": {
+    "message": "Reconnect when ready by reopening DevTools."
+  },
+  "ui/SearchableView.js | cancel": {
+    "message": "Cancel"
+  },
+  "ui/SearchableView.js | dMatches": {
+    "message": "{PH1} matches"
+  },
+  "ui/SearchableView.js | dOfD": {
+    "message": "{PH1} of {PH2}"
+  },
+  "ui/SearchableView.js | findString": {
+    "message": "Find"
+  },
+  "ui/SearchableView.js | matchCase": {
+    "message": "Match Case"
+  },
+  "ui/SearchableView.js | matchString": {
+    "message": "1 match"
+  },
+  "ui/SearchableView.js | replace": {
+    "message": "Replace"
+  },
+  "ui/SearchableView.js | replaceAll": {
+    "message": "Replace all"
+  },
+  "ui/SearchableView.js | searchNext": {
+    "message": "Search next"
+  },
+  "ui/SearchableView.js | searchPrevious": {
+    "message": "Search previous"
+  },
+  "ui/SearchableView.js | useRegularExpression": {
+    "message": "Use Regular Expression"
+  },
+  "ui/SettingsUI.js | oneOrMoreSettingsHaveChanged": {
+    "message": "One or more settings have changed which requires a reload to take effect."
+  },
+  "ui/SettingsUI.js | srequiresReload": {
+    "message": "{PH1}Requires reload"
+  },
+  "ui/SoftContextMenu.js | checked": {
+    "message": "checked"
+  },
+  "ui/SoftContextMenu.js | sS": {
+    "message": "{PH1}, {PH2}"
+  },
+  "ui/SoftContextMenu.js | sSS": {
+    "message": "{PH1}, {PH2}, {PH3}"
+  },
+  "ui/SoftContextMenu.js | unchecked": {
+    "message": "unchecked"
+  },
+  "ui/SoftDropDown.js | noItemSelected": {
+    "message": "(no item selected)"
+  },
+  "ui/SplitWidget.js | hideS": {
+    "message": "Hide {PH1}"
+  },
+  "ui/SplitWidget.js | showS": {
+    "message": "Show {PH1}"
+  },
+  "ui/SuggestBox.js | sSuggestionSOfS": {
+    "message": "{PH1}, suggestion {PH2} of {PH3}"
+  },
+  "ui/TabbedPane.js | close": {
+    "message": "Close"
+  },
+  "ui/TabbedPane.js | closeAll": {
+    "message": "Close all"
+  },
+  "ui/TabbedPane.js | closeOthers": {
+    "message": "Close others"
+  },
+  "ui/TabbedPane.js | closeS": {
+    "message": "Close {PH1}"
+  },
+  "ui/TabbedPane.js | closeTabsToTheRight": {
+    "message": "Close tabs to the right"
+  },
+  "ui/TabbedPane.js | moreTabs": {
+    "message": "More tabs"
+  },
+  "ui/TargetCrashedScreen.js | devtoolsWasDisconnectedFromThe": {
+    "message": "DevTools was disconnected from the page."
+  },
+  "ui/TargetCrashedScreen.js | oncePageIsReloadedDevtoolsWill": {
+    "message": "Once page is reloaded, DevTools will automatically reconnect."
+  },
+  "ui/UIUtils.js | anonymous": {
+    "message": "(anonymous)"
+  },
+  "ui/UIUtils.js | anotherProfilerIsAlreadyActive": {
+    "message": "Another profiler is already active"
+  },
+  "ui/UIUtils.js | asyncCall": {
+    "message": "Async Call"
+  },
+  "ui/UIUtils.js | cancel": {
+    "message": "Cancel"
+  },
+  "ui/UIUtils.js | close": {
+    "message": "Close"
+  },
+  "ui/UIUtils.js | copyFileName": {
+    "message": "Copy file name"
+  },
+  "ui/UIUtils.js | copyLinkAddress": {
+    "message": "Copy link address"
+  },
+  "ui/UIUtils.js | fdays": {
+    "message": "{PH1} days"
+  },
+  "ui/UIUtils.js | fhrs": {
+    "message": "{PH1} hrs"
+  },
+  "ui/UIUtils.js | fmin": {
+    "message": "{PH1} min"
+  },
+  "ui/UIUtils.js | fmms": {
+    "message": "{PH1} μs"
+  },
+  "ui/UIUtils.js | fms": {
+    "message": "{PH1} ms"
+  },
+  "ui/UIUtils.js | fs": {
+    "message": "{PH1} s"
+  },
+  "ui/UIUtils.js | ok": {
+    "message": "OK"
+  },
+  "ui/UIUtils.js | openInNewTab": {
+    "message": "Open in new tab"
+  },
+  "ui/UIUtils.js | promiseRejectedAsync": {
+    "message": "Promise rejected (async)"
+  },
+  "ui/UIUtils.js | promiseResolvedAsync": {
+    "message": "Promise resolved (async)"
+  },
+  "ui/UIUtils.js | sAsync": {
+    "message": "{PH1} (async)"
+  },
+  "ui/ViewManager.js | sPanel": {
+    "message": "{PH1} panel"
+  },
   "web_audio/AudioContextContentBuilder.ts | audiocontext": {
     "message": "AudioContext"
   },
diff --git a/front_end/i18n/locales/en-XL.json b/front_end/i18n/locales/en-XL.json
index 6eff2db..98db078 100644
--- a/front_end/i18n/locales/en-XL.json
+++ b/front_end/i18n/locales/en-XL.json
@@ -9431,6 +9431,246 @@
   "timeline/UIDevtoolsUtils.js | system": {
     "message": "Ŝýŝt́êḿ"
   },
+  "ui/components/DataGrid.ts | headerOptions": {
+    "message": "Ĥéâd́êŕ Ôṕt̂íôńŝ"
+  },
+  "ui/components/DataGrid.ts | resetColumns": {
+    "message": "R̂éŝét̂ Ćôĺûḿn̂ś"
+  },
+  "ui/components/DataGrid.ts | sortBy": {
+    "message": "Ŝór̂t́ B̂ý"
+  },
+  "ui/components/SurveyLink.ts | anErrorOccurredWithTheSurvey": {
+    "message": "Âń êŕr̂ór̂ óĉćûŕr̂éd̂ ẃît́ĥ t́ĥé ŝúr̂v́êý"
+  },
+  "ui/components/SurveyLink.ts | openingSurvey": {
+    "message": "Ôṕêńîńĝ śûŕv̂éŷ …"
+  },
+  "ui/components/SurveyLink.ts | thankYouForYourFeedback": {
+    "message": "T̂h́âńk̂ ýôú f̂ór̂ ýôúr̂ f́êéd̂b́âćk̂"
+  },
+  "ui/DockController.js | close": {
+    "message": "Ĉĺôśê"
+  },
+  "ui/DockController.js | dockToBottom": {
+    "message": "D̂óĉḱ t̂ó b̂ót̂t́ôḿ"
+  },
+  "ui/DockController.js | dockToLeft": {
+    "message": "D̂óĉḱ t̂ó l̂éf̂t́"
+  },
+  "ui/DockController.js | dockToRight": {
+    "message": "D̂óĉḱ t̂ó r̂íĝh́t̂"
+  },
+  "ui/DockController.js | undockIntoSeparateWindow": {
+    "message": "Ûńd̂óĉḱ îńt̂ó ŝép̂ár̂át̂é ŵín̂d́ôẃ"
+  },
+  "ui/EmptyWidget.js | learnMore": {
+    "message": "L̂éâŕn̂ ḿôŕê"
+  },
+  "ui/FilterBar.js | allStrings": {
+    "message": "Âĺl̂"
+  },
+  "ui/FilterBar.js | egSmalldUrlacomb": {
+    "message": "ê.ǵ. /small[d]+/ url:a.com/b"
+  },
+  "ui/FilterBar.js | filter": {
+    "message": "F̂íl̂t́êŕ"
+  },
+  "ui/FilterBar.js | sclickToSelectMultipleTypes": {
+    "message": "{PH1}Ĉĺîćk̂ t́ô śêĺêćt̂ ḿûĺt̂íp̂ĺê t́ŷṕêś"
+  },
+  "ui/Infobar.js | close": {
+    "message": "Ĉĺôśê"
+  },
+  "ui/Infobar.js | dontShowAgain": {
+    "message": "D̂ón̂'t́ ŝh́ôẃ âǵâín̂"
+  },
+  "ui/Infobar.js | learnMore": {
+    "message": "L̂éâŕn̂ ḿôŕê"
+  },
+  "ui/InspectorView.js | closeDrawer": {
+    "message": "Ĉĺôśê d́r̂áŵér̂"
+  },
+  "ui/InspectorView.js | moreTools": {
+    "message": "M̂ór̂é T̂óôĺŝ"
+  },
+  "ui/InspectorView.js | moveToBottom": {
+    "message": "M̂óv̂é t̂ó b̂ót̂t́ôḿ"
+  },
+  "ui/InspectorView.js | moveToTop": {
+    "message": "M̂óv̂é t̂ó t̂óp̂"
+  },
+  "ui/InspectorView.js | panels": {
+    "message": "P̂án̂él̂ś"
+  },
+  "ui/InspectorView.js | reloadDevtools": {
+    "message": "R̂él̂óâd́ D̂év̂T́ôól̂ś"
+  },
+  "ui/ListWidget.js | addString": {
+    "message": "Âd́d̂"
+  },
+  "ui/ListWidget.js | cancelString": {
+    "message": "Ĉán̂ćêĺ"
+  },
+  "ui/ListWidget.js | editString": {
+    "message": "Êd́ît́"
+  },
+  "ui/ListWidget.js | removeString": {
+    "message": "R̂ém̂óv̂é"
+  },
+  "ui/ListWidget.js | saveString": {
+    "message": "Ŝáv̂é"
+  },
+  "ui/RemoteDebuggingTerminatedScreen.js | reconnectDevtools": {
+    "message": "R̂éĉón̂ńêćt̂ D́êv́T̂óôĺŝ"
+  },
+  "ui/RemoteDebuggingTerminatedScreen.js | reconnectWhenReadyByReopening": {
+    "message": "R̂éĉón̂ńêćt̂ ẃĥén̂ ŕêád̂ý b̂ý r̂éôṕêńîńĝ D́êv́T̂óôĺŝ."
+  },
+  "ui/SearchableView.js | cancel": {
+    "message": "Ĉán̂ćêĺ"
+  },
+  "ui/SearchableView.js | dMatches": {
+    "message": "{PH1} m̂át̂ćĥéŝ"
+  },
+  "ui/SearchableView.js | dOfD": {
+    "message": "{PH1} ôf́ {PH2}"
+  },
+  "ui/SearchableView.js | findString": {
+    "message": "F̂ín̂d́"
+  },
+  "ui/SearchableView.js | matchCase": {
+    "message": "M̂át̂ćĥ Ćâśê"
+  },
+  "ui/SearchableView.js | matchString": {
+    "message": "1 m̂át̂ćĥ"
+  },
+  "ui/SearchableView.js | replace": {
+    "message": "R̂ép̂ĺâćê"
+  },
+  "ui/SearchableView.js | replaceAll": {
+    "message": "R̂ép̂ĺâćê ál̂ĺ"
+  },
+  "ui/SearchableView.js | searchNext": {
+    "message": "Ŝéâŕĉh́ n̂éx̂t́"
+  },
+  "ui/SearchableView.js | searchPrevious": {
+    "message": "Ŝéâŕĉh́ p̂ŕêv́îóûś"
+  },
+  "ui/SearchableView.js | useRegularExpression": {
+    "message": "Ûśê Ŕêǵûĺâŕ Êx́p̂ŕêśŝíôń"
+  },
+  "ui/SettingsUI.js | oneOrMoreSettingsHaveChanged": {
+    "message": "Ôńê ór̂ ḿôŕê śêt́t̂ín̂ǵŝ h́âv́ê ćĥán̂ǵêd́ ŵh́îćĥ ŕêq́ûír̂éŝ á r̂él̂óâd́ t̂ó t̂ák̂é êf́f̂éĉt́."
+  },
+  "ui/SettingsUI.js | srequiresReload": {
+    "message": "{PH1}R̂éq̂úîŕêś r̂él̂óâd́"
+  },
+  "ui/SoftContextMenu.js | checked": {
+    "message": "ĉh́êćk̂éd̂"
+  },
+  "ui/SoftContextMenu.js | sS": {
+    "message": "{PH1}, {PH2}"
+  },
+  "ui/SoftContextMenu.js | sSS": {
+    "message": "{PH1}, {PH2}, {PH3}"
+  },
+  "ui/SoftContextMenu.js | unchecked": {
+    "message": "ûńĉh́êćk̂éd̂"
+  },
+  "ui/SoftDropDown.js | noItemSelected": {
+    "message": "(n̂ó ît́êḿ ŝél̂éĉt́êd́)"
+  },
+  "ui/SplitWidget.js | hideS": {
+    "message": "Ĥíd̂é {PH1}"
+  },
+  "ui/SplitWidget.js | showS": {
+    "message": "Ŝh́ôẃ {PH1}"
+  },
+  "ui/SuggestBox.js | sSuggestionSOfS": {
+    "message": "{PH1}, ŝúĝǵêśt̂íôń {PH2} ôf́ {PH3}"
+  },
+  "ui/TabbedPane.js | close": {
+    "message": "Ĉĺôśê"
+  },
+  "ui/TabbedPane.js | closeAll": {
+    "message": "Ĉĺôśê ál̂ĺ"
+  },
+  "ui/TabbedPane.js | closeOthers": {
+    "message": "Ĉĺôśê ót̂h́êŕŝ"
+  },
+  "ui/TabbedPane.js | closeS": {
+    "message": "Ĉĺôśê {PH1}"
+  },
+  "ui/TabbedPane.js | closeTabsToTheRight": {
+    "message": "Ĉĺôśê t́âb́ŝ t́ô t́ĥé r̂íĝh́t̂"
+  },
+  "ui/TabbedPane.js | moreTabs": {
+    "message": "M̂ór̂é t̂áb̂ś"
+  },
+  "ui/TargetCrashedScreen.js | devtoolsWasDisconnectedFromThe": {
+    "message": "D̂év̂T́ôól̂ś ŵáŝ d́îśĉón̂ńêćt̂éd̂ f́r̂óm̂ t́ĥé p̂áĝé."
+  },
+  "ui/TargetCrashedScreen.js | oncePageIsReloadedDevtoolsWill": {
+    "message": "Ôńĉé p̂áĝé îś r̂él̂óâd́êd́, D̂év̂T́ôól̂ś ŵíl̂ĺ âút̂óm̂át̂íĉál̂ĺŷ ŕêćôńn̂éĉt́."
+  },
+  "ui/UIUtils.js | anonymous": {
+    "message": "(âńôńŷḿôúŝ)"
+  },
+  "ui/UIUtils.js | anotherProfilerIsAlreadyActive": {
+    "message": "Âńôt́ĥér̂ ṕr̂óf̂íl̂ér̂ íŝ ál̂ŕêád̂ý âćt̂ív̂é"
+  },
+  "ui/UIUtils.js | asyncCall": {
+    "message": "Âśŷńĉ Ćâĺl̂"
+  },
+  "ui/UIUtils.js | cancel": {
+    "message": "Ĉán̂ćêĺ"
+  },
+  "ui/UIUtils.js | close": {
+    "message": "Ĉĺôśê"
+  },
+  "ui/UIUtils.js | copyFileName": {
+    "message": "Ĉóp̂ý f̂íl̂é n̂ám̂é"
+  },
+  "ui/UIUtils.js | copyLinkAddress": {
+    "message": "Ĉóp̂ý l̂ín̂ḱ âd́d̂ŕêśŝ"
+  },
+  "ui/UIUtils.js | fdays": {
+    "message": "{PH1} d̂áŷś"
+  },
+  "ui/UIUtils.js | fhrs": {
+    "message": "{PH1} ĥŕŝ"
+  },
+  "ui/UIUtils.js | fmin": {
+    "message": "{PH1} m̂ín̂"
+  },
+  "ui/UIUtils.js | fmms": {
+    "message": "{PH1} μŝ"
+  },
+  "ui/UIUtils.js | fms": {
+    "message": "{PH1} m̂ś"
+  },
+  "ui/UIUtils.js | fs": {
+    "message": "{PH1} ŝ"
+  },
+  "ui/UIUtils.js | ok": {
+    "message": "ÔḰ"
+  },
+  "ui/UIUtils.js | openInNewTab": {
+    "message": "Ôṕêń îń n̂éŵ t́âb́"
+  },
+  "ui/UIUtils.js | promiseRejectedAsync": {
+    "message": "P̂ŕôḿîśê ŕêj́êćt̂éd̂ (áŝýn̂ć)"
+  },
+  "ui/UIUtils.js | promiseResolvedAsync": {
+    "message": "P̂ŕôḿîśê ŕêśôĺv̂éd̂ (áŝýn̂ć)"
+  },
+  "ui/UIUtils.js | sAsync": {
+    "message": "{PH1} (âśŷńĉ)"
+  },
+  "ui/ViewManager.js | sPanel": {
+    "message": "{PH1} p̂án̂él̂"
+  },
   "web_audio/AudioContextContentBuilder.ts | audiocontext": {
     "message": "Âúd̂íôĆôńt̂éx̂t́"
   },
diff --git a/front_end/langpacks/devtools_ui_strings.grd b/front_end/langpacks/devtools_ui_strings.grd
index 12ccbb0..b2903d2 100644
--- a/front_end/langpacks/devtools_ui_strings.grd
+++ b/front_end/langpacks/devtools_ui_strings.grd
@@ -20,8 +20,6 @@
       <part file="../main/main_strings.grdp" />
       <part file="../quick_open/quick_open_strings.grdp" />
       <part file="../sdk/sdk_strings.grdp" />
-      <part file="../ui/components/components_strings.grdp" />
-      <part file="../ui/ui_strings.grdp" />
       <part file="shared_strings.grdp" />
     </messages>
   </release>
diff --git a/front_end/langpacks/shared_strings.grdp b/front_end/langpacks/shared_strings.grdp
index f851465..44c2082 100644
--- a/front_end/langpacks/shared_strings.grdp
+++ b/front_end/langpacks/shared_strings.grdp
@@ -1,9 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- Strings in this file are shared, i.e. they appear multiple times. -->
 <grit-part>
-  <message name="IDS_DEVTOOLS_0b484cfcf50c8fabff48c0aad426f544" desc="Text to dock the DevTools to the left of the browser tab">
-    Dock to left
-  </message>
   <message name="IDS_DEVTOOLS_29260f495ba8adcc62fd1307c758ff4e" desc="Text to show the measuring rulers on the target">
     Show rulers
   </message>
@@ -11,51 +8,21 @@
     Media
   </message>
 
-  <message name="IDS_DEVTOOLS_4789f23283b3a61f858b641a1bef19a3" desc="Text for the memory of the page">
-    Memory
-  </message>
   <message name="IDS_DEVTOOLS_4cc6684df7b4a92b1dec6fce3264fac8" desc="Text describing global shortcuts and settings that are available throughout the DevTools">
     Global
   </message>
-  <message name="IDS_DEVTOOLS_6a26f548831e6a8c26bfbbd9f6ec61e0" desc="Text for the viewing the help options">
-    Help
-  </message>
-  <message name="IDS_DEVTOOLS_6feab1a8f70b4209f82a628b7395ede3" desc="Message to display if a setting change requires a reload of DevTools">
-    One or more settings have changed which requires a reload to take effect.
-  </message>
-  <message name="IDS_DEVTOOLS_72507d307327a430052f9fcd914dfaee" desc="Title of an action that reloads the DevTools">
-    Reload DevTools
-  </message>
   <message name="IDS_DEVTOOLS_87d17f4624a514e81dc7c8e016a7405c" desc="Text for the mobile platform, as opposed to desktop">
     Mobile
   </message>
   <message name="IDS_DEVTOOLS_886f598a8a9e6a4bfe0c09fcf7779611" desc="Title of a Rendering setting that can be invoked through the Command Menu">
     Emulate a focused page
   </message>
-  <message name="IDS_DEVTOOLS_9446a98ad14416153cc4d45ab8b531bf" desc="Text for the performance of something">
-    Performance
-  </message>
   <message name="IDS_DEVTOOLS_a02c83a7dbd96295beaefb72c2bee2de" desc="Text that refers to the main target">
     Main
   </message>
   <message name="IDS_DEVTOOLS_a6e8f9aed2ac6481dc25a18a33342d03" desc="Title of the Rendering tool">
     Rendering
   </message>
-  <message name="IDS_DEVTOOLS_aa56a2e65d8106aef3c61e4f6bf94fdb" desc="Title of the Elements Panel">
-    Elements
-  </message>
-  <message name="IDS_DEVTOOLS_af29aa178ae43211319e28f627e96590" desc="Title of an action in the emulation tool to show sensors">
-    Sensors
-  </message>
-  <message name="IDS_DEVTOOLS_b94d8a074eddd267702810179875737f" desc="Text that refers to the debugger">
-    Debugger
-  </message>
-  <message name="IDS_DEVTOOLS_b9dee6bade160c89fb7f0e539d453513" desc="Text to dock the DevTools to the bottom of the browser tab">
-    Dock to bottom
-  </message>
-  <message name="IDS_DEVTOOLS_bccaa4aa80831b76c11240a16447975f" desc="Title of the Console tool">
-    Console
-  </message>
   <message name="IDS_DEVTOOLS_bec25a46972e4fa86df9413508add5c2" desc="Text that refers to disabling local fonts">
     Disable local fonts
   </message>
@@ -65,25 +32,13 @@
   <message name="IDS_DEVTOOLS_e402c138065e7eece783dc30c6079192" desc="Text that appears on a button for the xhr resource type filter.">
     XHR
   </message>
-  <message name="IDS_DEVTOOLS_eec89088ee408b80387155272b113256" desc="Title of the Network tool">
-    Network
-  </message>
   <message name="IDS_DEVTOOLS_ef95393ad48336d7c3543625354a3d56" desc="Text to highlight the rendering frames for ads">
     Highlight ad frames
   </message>
   <message name="IDS_DEVTOOLS_f0f31c9700c6b10d8a20dc487b2ae6a8" desc="Text for the touch type to simulate on a device">
     Touch
   </message>
-  <message name="IDS_DEVTOOLS_f53944c3a55bdb5ad65c6226e358a626" desc="Text to undock the DevTools">
-    Undock into separate window
-  </message>
   <message name="IDS_DEVTOOLS_f907e651164789346ae0a1e257c462d8" desc="Label for a group of JavaScript files">
     Script
   </message>
-  <message name="IDS_DEVTOOLS_fb61758d0f0fda4ba867c3d5a46c16a7" desc="Name of the Sources panel">
-    Sources
-  </message>
-  <message name="IDS_DEVTOOLS_fe7fb037b290768d6a6be30b237e183d" desc="Text to dock the DevTools to the right of the browser tab">
-    Dock to right
-  </message>
 </grit-part>
diff --git a/front_end/main/main_strings.grdp b/front_end/main/main_strings.grdp
index a87fe45..d904c2e 100644
--- a/front_end/main/main_strings.grdp
+++ b/front_end/main/main_strings.grdp
@@ -15,6 +15,9 @@
   <message name="IDS_DEVTOOLS_0a0afb342478f201b92cbc89d19bf14d" desc="Title of a setting under the Appearance category that can be invoked through the Command Menu">
     Switch to dark theme
   </message>
+  <message name="IDS_DEVTOOLS_0b484cfcf50c8fabff48c0aad426f544" desc="Text to dock the DevTools to the left of the browser tab">
+    Dock to left
+  </message>
   <message name="IDS_DEVTOOLS_15fa1acc2a998159c4ed2a950c5c231d" desc="Text in the Shortcuts page in settings to explain a keyboard shortcut">
     Toggle drawer
   </message>
@@ -57,6 +60,12 @@
   <message name="IDS_DEVTOOLS_60737985de866df2b4fee4562844ce8a" desc="A message to display prompting the user to reload DevTools if the OS color scheme changes.">
     The system-preferred color scheme has changed. To apply this change to DevTools, reload.
   </message>
+  <message name="IDS_DEVTOOLS_6a26f548831e6a8c26bfbbd9f6ec61e0" desc="Text for the viewing the help options">
+    Help
+  </message>
+  <message name="IDS_DEVTOOLS_72507d307327a430052f9fcd914dfaee" desc="Title of an action that reloads the DevTools">
+    Reload DevTools
+  </message>
   <message name="IDS_DEVTOOLS_7b91156d64b76a5dda815937fce9119d" desc="Text in the Shortcuts page to explain a keyboard shortcut (zoom in)">
     Zoom in
   </message>
@@ -99,6 +108,9 @@
   <message name="IDS_DEVTOOLS_b9cd538a753713464d2ea17d7e975041" desc="A context menu item in the Main">
     More tools
   </message>
+  <message name="IDS_DEVTOOLS_b9dee6bade160c89fb7f0e539d453513" desc="Text to dock the DevTools to the bottom of the browser tab">
+    Dock to bottom
+  </message>
   <message name="IDS_DEVTOOLS_c0fef4f5cd015e4b1e5477f511dc3939" desc="Title of a setting under the Appearance category that can be invoked through the Command Menu">
     Use automatic panel layout
   </message>
@@ -141,10 +153,16 @@
   <message name="IDS_DEVTOOLS_f52a9fce93c15e9340054e40f837a7ef" desc="Title of an action that navigates to the next panel">
     Next panel
   </message>
+  <message name="IDS_DEVTOOLS_f53944c3a55bdb5ad65c6226e358a626" desc="Text to undock the DevTools">
+    Undock into separate window
+  </message>
   <message name="IDS_DEVTOOLS_fa480abba67730dd6bd15aa40308d78a" desc="Title of a setting under the Appearance category that can be invoked through the Command Menu">
     Set color format to HSL
   </message>
   <message name="IDS_DEVTOOLS_fa4ab936aaa8ad819e491af0ec0b674b" desc="Title of a setting under the Appearance category that can be invoked through the Command Menu">
     Switch to system preferred color theme
   </message>
+  <message name="IDS_DEVTOOLS_fe7fb037b290768d6a6be30b237e183d" desc="Text to dock the DevTools to the right of the browser tab">
+    Dock to right
+  </message>
 </grit-part>
diff --git a/front_end/quick_open/quick_open_strings.grdp b/front_end/quick_open/quick_open_strings.grdp
index 88c33a2..34b1f21 100644
--- a/front_end/quick_open/quick_open_strings.grdp
+++ b/front_end/quick_open/quick_open_strings.grdp
@@ -9,6 +9,9 @@
   <message name="IDS_DEVTOOLS_532ce4f18bb96f70d8ee338082ad7ed0" desc="Title of quick open dialog">
     Quick open
   </message>
+  <message name="IDS_DEVTOOLS_6feab1a8f70b4209f82a628b7395ede3" desc="Message to display if a setting change requires a reload of DevTools">
+    One or more settings have changed which requires a reload to take effect.
+  </message>
   <message name="IDS_DEVTOOLS_74540c79e377bea903e1023a46df5574" desc="Text to open a file">
     Open file
   </message>
diff --git a/front_end/ui/ActionRegistration.ts b/front_end/ui/ActionRegistration.ts
index 554477a..23f9867 100644
--- a/front_end/ui/ActionRegistration.ts
+++ b/front_end/ui/ActionRegistration.ts
@@ -4,7 +4,6 @@
 
 import * as Common from '../common/common.js';
 import * as Platform from '../platform/platform.js';
-import {ls} from '../platform/platform.js';
 import * as Root from '../root/root.js';
 
 import {Context} from './Context.js';
@@ -177,28 +176,29 @@
   Toggled: Symbol('Toggled'),
 };
 
+// TODO(crbug.com/1181019)
 export const ActionCategory = {
-  ELEMENTS: ls`Elements`,
-  SCREENSHOT: ls`Screenshot`,
-  NETWORK: ls`Network`,
-  MEMORY: ls`Memory`,
-  JAVASCRIPT_PROFILER: ls`JavaScript Profiler`,
-  CONSOLE: ls`Console`,
-  PERFORMANCE: ls`Performance`,
-  MOBILE: ls`Mobile`,
-  SENSORS: ls`Sensors`,
-  HELP: ls`Help`,
-  INPUTS: ls`Inputs`,
-  LAYERS: ls`Layers`,
-  NAVIGATION: ls`Navigation`,
-  DRAWER: ls`Drawer`,
-  GLOBAL: ls`Global`,
-  RESOURCES: ls`Resources`,
-  BACKGROUND_SERVICES: ls`Background Services`,
-  SETTINGS: ls`Settings`,
-  DEBUGGER: ls`Debugger`,
-  RECORDER: ls`Recorder`,
-  SOURCES: ls`Sources`,
+  ELEMENTS: 'Elements',
+  SCREENSHOT: 'Screenshot',
+  NETWORK: 'Network',
+  MEMORY: 'Memory',
+  JAVASCRIPT_PROFILER: 'JavaScript Profiler',
+  CONSOLE: 'Console',
+  PERFORMANCE: 'Performance',
+  MOBILE: 'Mobile',
+  SENSORS: 'Sensors',
+  HELP: 'Help',
+  INPUTS: 'Inputs',
+  LAYERS: 'Layers',
+  NAVIGATION: 'Navigation',
+  DRAWER: 'Drawer',
+  GLOBAL: 'Global',
+  RESOURCES: 'Resources',
+  BACKGROUND_SERVICES: 'Background Services',
+  SETTINGS: 'Settings',
+  DEBUGGER: 'Debugger',
+  RECORDER: 'Recorder',
+  SOURCES: 'Sources',
 };
 
 type ActionCategory = typeof ActionCategory[keyof typeof ActionCategory];
diff --git a/front_end/ui/BUILD.gn b/front_end/ui/BUILD.gn
index 934aec5..1dca460 100644
--- a/front_end/ui/BUILD.gn
+++ b/front_end/ui/BUILD.gn
@@ -70,6 +70,7 @@
     "../common:bundle",
     "../dom_extension:bundle",
     "../host:bundle",
+    "../i18n:bundle",
     "../platform:bundle",
     "../text_utils:bundle",
     "../theme_support:bundle",
diff --git a/front_end/ui/DockController.js b/front_end/ui/DockController.js
index 95013a5..eaf0615 100644
--- a/front_end/ui/DockController.js
+++ b/front_end/ui/DockController.js
@@ -30,11 +30,36 @@
 
 import * as Common from '../common/common.js';
 import * as Host from '../host/host.js';
+import * as i18n from '../i18n/i18n.js';
 
 import {ActionDelegate} from './ActionRegistration.js';             // eslint-disable-line no-unused-vars
 import {Context} from './Context.js';                               // eslint-disable-line no-unused-vars
 import {Provider, ToolbarButton, ToolbarItem} from './Toolbar.js';  // eslint-disable-line no-unused-vars
 
+export const UIStrings = {
+  /**
+  *@description Text to close something
+  */
+  close: 'Close',
+  /**
+  *@description Text to dock the DevTools to the right of the browser tab
+  */
+  dockToRight: 'Dock to right',
+  /**
+  *@description Text to dock the DevTools to the bottom of the browser tab
+  */
+  dockToBottom: 'Dock to bottom',
+  /**
+  *@description Text to dock the DevTools to the left of the browser tab
+  */
+  dockToLeft: 'Dock to left',
+  /**
+  *@description Text to undock the DevTools
+  */
+  undockIntoSeparateWindow: 'Undock into separate window',
+};
+const str_ = i18n.i18n.registerUIStrings('ui/DockController.js', UIStrings);
+const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
 /** @type {!DockController} */
 let dockControllerInstance;
 
@@ -46,7 +71,7 @@
     super();
     this._canDock = canDock;
 
-    this._closeButton = new ToolbarButton(Common.UIString.UIString('Close'), 'largeicon-delete');
+    this._closeButton = new ToolbarButton(i18nString(UIStrings.close), 'largeicon-delete');
     this._closeButton.addEventListener(
         ToolbarButton.Events.Click,
         Host.InspectorFrontendHost.InspectorFrontendHostInstance.closeWindow.bind(
@@ -92,8 +117,8 @@
     }
 
     this._titles = [
-      Common.UIString.UIString('Dock to right'), Common.UIString.UIString('Dock to bottom'),
-      Common.UIString.UIString('Dock to left'), Common.UIString.UIString('Undock into separate window')
+      i18nString(UIStrings.dockToRight), i18nString(UIStrings.dockToBottom), i18nString(UIStrings.dockToLeft),
+      i18nString(UIStrings.undockIntoSeparateWindow)
     ];
     this._dockSideChanged();
   }
diff --git a/front_end/ui/EmptyWidget.js b/front_end/ui/EmptyWidget.js
index 08ce41d..c53be79 100644
--- a/front_end/ui/EmptyWidget.js
+++ b/front_end/ui/EmptyWidget.js
@@ -28,10 +28,19 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import {ls} from '../platform/platform.js';
+import * as i18n from '../i18n/i18n.js';
+
 import {VBox} from './Widget.js';
 import {XLink} from './XLink.js';
 
+export const UIStrings = {
+  /**
+  *@description Text that is usually a hyperlink to more documentation
+  */
+  learnMore: 'Learn more',
+};
+const str_ = i18n.i18n.registerUIStrings('ui/EmptyWidget.js', UIStrings);
+const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
 
 export class EmptyWidget extends VBox {
   /**
@@ -58,7 +67,8 @@
    * @return {!HTMLElement}
    */
   appendLink(link) {
-    return /** @type {!HTMLElement} */ (this._contentElement.appendChild(XLink.create(link, ls`Learn more`)));
+    return /** @type {!HTMLElement} */ (
+        this._contentElement.appendChild(XLink.create(link, i18nString(UIStrings.learnMore))));
   }
 
   /**
diff --git a/front_end/ui/FilterBar.js b/front_end/ui/FilterBar.js
index 1879f87..e7d3d73 100644
--- a/front_end/ui/FilterBar.js
+++ b/front_end/ui/FilterBar.js
@@ -30,6 +30,7 @@
 
 import * as Common from '../common/common.js';
 import * as Host from '../host/host.js';
+import * as i18n from '../i18n/i18n.js';
 
 import * as ARIAUtils from './ARIAUtils.js';
 import {Icon} from './Icon.js';
@@ -42,6 +43,27 @@
 import {CheckboxLabel, createTextChild} from './UIUtils.js';
 import {HBox} from './Widget.js';
 
+export const UIStrings = {
+  /**
+  *@description Text to filter result items
+  */
+  filter: 'Filter',
+  /**
+  *@description Text that appears when hover over the filter bar in the Network tool
+  */
+  egSmalldUrlacomb: 'e.g. `/small[\d]+/ url:a.com/b`',
+  /**
+  *@description Text that appears when hover over the All button in the Network tool
+  *@example {Ctrl + } PH1
+  */
+  sclickToSelectMultipleTypes: '{PH1}Click to select multiple types',
+  /**
+  *@description Text for everything
+  */
+  allStrings: 'All',
+};
+const str_ = i18n.i18n.registerUIStrings('ui/FilterBar.js', UIStrings);
+const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
 export class FilterBar extends HBox {
   /**
    * @param {string} name
@@ -55,8 +77,7 @@
 
     this._stateSetting =
         Common.Settings.Settings.instance().createSetting('filterBar-' + name + '-toggled', Boolean(visibleByDefault));
-    this._filterButton =
-        new ToolbarSettingToggle(this._stateSetting, 'largeicon-filter', Common.UIString.UIString('Filter'));
+    this._filterButton = new ToolbarSettingToggle(this._stateSetting, 'largeicon-filter', i18nString(UIStrings.filter));
 
     /** @type {!Array<!FilterUI>} */
     this._filters = [];
@@ -208,8 +229,8 @@
     this._prompt.initialize(this._completions.bind(this), ' ', true);
     /** @type {!HTMLElement} */
     this._proxyElement = /** @type {!HTMLElement} */ (this._prompt.attach(this._filterInputElement));
-    Tooltip.install(this._proxyElement, Common.UIString.UIString('e.g. /small[\\d]+/ url:a.com/b'));
-    this._prompt.setPlaceholder(Common.UIString.UIString('Filter'));
+    Tooltip.install(this._proxyElement, i18nString(UIStrings.egSmalldUrlacomb));
+    this._prompt.setPlaceholder(i18nString(UIStrings.filter));
     this._prompt.addEventListener(Events.TextChanged, this._valueChanged.bind(this));
 
     /** @type {?function(string, string, boolean=):!Promise<!Suggestions>} */
@@ -307,10 +328,9 @@
     this._filtersElement.classList.add('filter-bitset-filter');
     ARIAUtils.markAsListBox(this._filtersElement);
     ARIAUtils.markAsMultiSelectable(this._filtersElement);
-    Tooltip.install(
-        this._filtersElement,
-        Common.UIString.UIString(
-            '%sClick to select multiple types', KeyboardShortcut.shortcutToString('', Modifiers.CtrlOrMeta)));
+    Tooltip.install(this._filtersElement, i18nString(UIStrings.sclickToSelectMultipleTypes, {
+                      PH1: KeyboardShortcut.shortcutToString('', Modifiers.CtrlOrMeta)
+                    }));
 
     /** @type {!WeakMap<!HTMLElement, string>} */
     this._typeFilterElementTypeNames = new WeakMap();
@@ -318,7 +338,7 @@
     this._allowedTypes = new Set();
     /** @type {!Array.<!HTMLElement>} */
     this._typeFilterElements = [];
-    this._addBit(NamedBitSetFilterUI.ALL_TYPES, Common.UIString.UIString('All'));
+    this._addBit(NamedBitSetFilterUI.ALL_TYPES, i18nString(UIStrings.allStrings));
     this._typeFilterElements[0].tabIndex = 0;
     this._filtersElement.createChild('div', 'filter-bitset-filter-divider');
 
diff --git a/front_end/ui/Infobar.js b/front_end/ui/Infobar.js
index e9d493b..7adfbfa 100644
--- a/front_end/ui/Infobar.js
+++ b/front_end/ui/Infobar.js
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 import * as Common from '../common/common.js';  // eslint-disable-line no-unused-vars
-import {ls} from '../platform/platform.js';
+import * as i18n from '../i18n/i18n.js';
 
 import * as ARIAUtils from './ARIAUtils.js';
 import {Keys} from './KeyboardShortcut.js';
@@ -11,6 +11,22 @@
 import {createShadowRootWithCoreStyles} from './utils/create-shadow-root-with-core-styles.js';
 import {Widget} from './Widget.js';  // eslint-disable-line no-unused-vars
 
+export const UIStrings = {
+  /**
+  *@description Text on a button to close the infobar and never show the infobar in the future
+  */
+  dontShowAgain: 'Don\'t show again',
+  /**
+  *@description Text that is usually a hyperlink to more documentation
+  */
+  learnMore: 'Learn more',
+  /**
+  *@description Text to close something
+  */
+  close: 'Close',
+};
+const str_ = i18n.i18n.registerUIStrings('ui/Infobar.js', UIStrings);
+const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
 export class Infobar {
   /**
    * @param {!Type} type
@@ -59,19 +75,20 @@
     /** @type {?Common.Settings.Setting<*>} */
     this._disableSetting = disableSetting || null;
     if (disableSetting) {
-      const disableButton = createTextButton(ls`Don't show again`, this._onDisable.bind(this), 'infobar-button');
+      const disableButton =
+          createTextButton(i18nString(UIStrings.dontShowAgain), this._onDisable.bind(this), 'infobar-button');
       this._actionContainer.appendChild(disableButton);
     }
 
     this._closeContainer = this._mainRow.createChild('div', 'infobar-close-container');
-    this._toggleElement =
-        createTextButton(ls`Learn more`, this._onToggleDetails.bind(this), 'link-style devtools-link hidden');
+    this._toggleElement = createTextButton(
+        i18nString(UIStrings.learnMore), this._onToggleDetails.bind(this), 'link-style devtools-link hidden');
     this._closeContainer.appendChild(this._toggleElement);
     this._closeButton = this._closeContainer.createChild('div', 'close-button', 'dt-close-button');
     // @ts-ignore This is a custom element defined in UIUitls.js that has a `setTabbable` that TS doesn't
     //            know about.
     this._closeButton.setTabbable(true);
-    ARIAUtils.setDescription(this._closeButton, ls`Close`);
+    ARIAUtils.setDescription(this._closeButton, i18nString(UIStrings.close));
     self.onInvokeElement(this._closeButton, this.dispose.bind(this));
 
     if (type !== Type.Issue) {
diff --git a/front_end/ui/InspectorView.js b/front_end/ui/InspectorView.js
index 58f4a52..3261c5d 100644
--- a/front_end/ui/InspectorView.js
+++ b/front_end/ui/InspectorView.js
@@ -30,7 +30,7 @@
 
 import * as Common from '../common/common.js';
 import * as Host from '../host/host.js';
-import {ls} from '../platform/platform.js';
+import * as i18n from '../i18n/i18n.js';
 import * as Root from '../root/root.js';
 
 import {ActionDelegate as ActionDelegateInterface} from './ActionRegistration.js';  // eslint-disable-line no-unused-vars
@@ -51,6 +51,34 @@
 import {ViewManager} from './ViewManager.js';
 import {VBox, WidgetFocusRestorer} from './Widget.js';
 
+export const UIStrings = {
+  /**
+  *@description Title of more tabs button in inspector view
+  */
+  moreTools: 'More Tools',
+  /**
+  *@description Text that appears when hovor over the close button on the drawer view
+  */
+  closeDrawer: 'Close drawer',
+  /**
+  *@description The aria label for main tabbed pane that contains Panels
+  */
+  panels: 'Panels',
+  /**
+  *@description Title of an action that reloads the DevTools
+  */
+  reloadDevtools: 'Reload DevTools',
+  /**
+  *@description Text for context menu action to move a tab to the main panel
+  */
+  moveToTop: 'Move to top',
+  /**
+  *@description Text for context menu action to move a tab to the drawer
+  */
+  moveToBottom: 'Move to bottom',
+};
+const str_ = i18n.i18n.registerUIStrings('ui/InspectorView.js', UIStrings);
+const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
 /** @type {!InspectorView} */
 let inspectorViewInstance;
 
@@ -75,11 +103,11 @@
     this._drawerTabbedLocation =
         ViewManager.instance().createTabbedLocation(this._showDrawer.bind(this, false), 'drawer-view', true, true);
     const moreTabsButton = this._drawerTabbedLocation.enableMoreTabsButton();
-    moreTabsButton.setTitle(ls`More Tools`);
+    moreTabsButton.setTitle(i18nString(UIStrings.moreTools));
     this._drawerTabbedPane = this._drawerTabbedLocation.tabbedPane();
     this._drawerTabbedPane.setMinimumSize(0, 27);
     this._drawerTabbedPane.element.classList.add('drawer-tabbed-pane');
-    const closeDrawerButton = new ToolbarButton(Common.UIString.UIString('Close drawer'), 'largeicon-delete');
+    const closeDrawerButton = new ToolbarButton(i18nString(UIStrings.closeDrawer), 'largeicon-delete');
     closeDrawerButton.addEventListener(ToolbarButton.Events.Click, this._closeDrawer, this);
     this._drawerTabbedPane.addEventListener(TabbedPaneEvents.TabSelected, this._tabSelected, this);
     this._drawerTabbedPane.setTabDelegate(this._tabDelegate);
@@ -105,7 +133,7 @@
     this._tabbedPane.element.classList.add('main-tabbed-pane');
     this._tabbedPane.registerRequiredCSS('ui/inspectorViewTabbedPane.css', {enableLegacyPatching: false});
     this._tabbedPane.addEventListener(TabbedPaneEvents.TabSelected, this._tabSelected, this);
-    this._tabbedPane.setAccessibleName(Common.UIString.UIString('Panels'));
+    this._tabbedPane.setAccessibleName(i18nString(UIStrings.panels));
     this._tabbedPane.setTabDelegate(this._tabDelegate);
 
     // Store the initial selected panel for use in launch histograms
@@ -427,7 +455,7 @@
     if (!this._reloadRequiredInfobar) {
       const infobar = new Infobar(InfobarType.Info, message, [
         {
-          text: ls`Reload DevTools`,
+          text: i18nString(UIStrings.reloadDevtools),
           highlight: true,
           delegate: () => {
             if (DockController.instance().canDock() && DockController.instance().dockSide() === State.Undocked) {
@@ -553,11 +581,9 @@
 
     const locationName = ViewManager.instance().locationNameForViewId(tabId);
     if (locationName === 'drawer-view') {
-      contextMenu.defaultSection().appendItem(
-          Common.UIString.UIString('Move to top'), this.moveToMainPanel.bind(this, tabId));
+      contextMenu.defaultSection().appendItem(i18nString(UIStrings.moveToTop), this.moveToMainPanel.bind(this, tabId));
     } else {
-      contextMenu.defaultSection().appendItem(
-          Common.UIString.UIString('Move to bottom'), this.moveToDrawer.bind(this, tabId));
+      contextMenu.defaultSection().appendItem(i18nString(UIStrings.moveToBottom), this.moveToDrawer.bind(this, tabId));
     }
   }
 }
diff --git a/front_end/ui/ListWidget.js b/front_end/ui/ListWidget.js
index bc95166..8625595 100644
--- a/front_end/ui/ListWidget.js
+++ b/front_end/ui/ListWidget.js
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import * as Common from '../common/common.js';
+
+import * as i18n from '../i18n/i18n.js';
 
 import * as ARIAUtils from './ARIAUtils.js';
 import {Toolbar, ToolbarButton} from './Toolbar.js';
@@ -10,6 +11,30 @@
 import {createInput, createTextButton, ElementFocusRestorer} from './UIUtils.js';
 import {VBox} from './Widget.js';
 
+export const UIStrings = {
+  /**
+  *@description Text on a button to start editing text
+  */
+  editString: 'Edit',
+  /**
+  *@description Label for an item to remove something
+  */
+  removeString: 'Remove',
+  /**
+  *@description Text to save something
+  */
+  saveString: 'Save',
+  /**
+  *@description Text to add something
+  */
+  addString: 'Add',
+  /**
+  *@description Text to cancel something
+  */
+  cancelString: 'Cancel',
+};
+const str_ = i18n.i18n.registerUIStrings('ui/ListWidget.js', UIStrings);
+const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
 /**
  * @template T
  */
@@ -148,11 +173,11 @@
 
     const toolbar = new Toolbar('', buttons);
 
-    const editButton = new ToolbarButton(Common.UIString.UIString('Edit'), 'largeicon-edit');
+    const editButton = new ToolbarButton(i18nString(UIStrings.editString), 'largeicon-edit');
     editButton.addEventListener(ToolbarButton.Events.Click, onEditClicked.bind(this));
     toolbar.appendToolbarItem(editButton);
 
-    const removeButton = new ToolbarButton(Common.UIString.UIString('Remove'), 'largeicon-trash-bin');
+    const removeButton = new ToolbarButton(i18nString(UIStrings.removeString), 'largeicon-trash-bin');
     removeButton.addEventListener(ToolbarButton.Events.Click, onRemoveClicked.bind(this));
     toolbar.appendToolbarItem(removeButton);
 
@@ -222,7 +247,7 @@
     this._updatePlaceholder();
     this._list.insertBefore(this._editor.element, insertionPoint);
     this._editor.beginEdit(
-        item, index, element ? Common.UIString.UIString('Save') : Common.UIString.UIString('Add'),
+        item, index, element ? i18nString(UIStrings.saveString) : i18nString(UIStrings.addString),
         this._commitEditing.bind(this), this._stopEditing.bind(this));
   }
 
@@ -309,7 +334,7 @@
     this._commitButton = createTextButton('', this._commitClicked.bind(this), '', true /* primary */);
     buttonsRow.appendChild(this._commitButton);
     this._cancelButton = createTextButton(
-        Common.UIString.UIString('Cancel'), this._cancelClicked.bind(this), '', true /* primary */, 'mousedown');
+        i18nString(UIStrings.cancelString), this._cancelClicked.bind(this), '', true /* primary */, 'mousedown');
     this._cancelButton.addEventListener(
         'keydown', onKeyDown.bind(null, event => event.key === 'Enter', this._cancelClicked.bind(this)), false);
     buttonsRow.appendChild(this._cancelButton);
diff --git a/front_end/ui/RemoteDebuggingTerminatedScreen.js b/front_end/ui/RemoteDebuggingTerminatedScreen.js
index 0826e58..050867e 100644
--- a/front_end/ui/RemoteDebuggingTerminatedScreen.js
+++ b/front_end/ui/RemoteDebuggingTerminatedScreen.js
@@ -1,13 +1,25 @@
 // Copyright 2018 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
+import * as i18n from '../i18n/i18n.js';
 
-import * as Common from '../common/common.js';
 import {Dialog} from './Dialog.js';
 import {SizeBehavior} from './GlassPane.js';
 import {createTextButton, formatLocalized} from './UIUtils.js';
 import {VBox} from './Widget.js';
 
+export const UIStrings = {
+  /**
+  *@description Text in a dialog box showing how to reconnect to DevTools when remote debugging has been terminated
+  */
+  reconnectWhenReadyByReopening: 'Reconnect when ready by reopening DevTools.',
+  /**
+  *@description Text on a button to reconnect Devtools when remote debugging terminated
+  */
+  reconnectDevtools: 'Reconnect DevTools'
+};
+const str_ = i18n.i18n.registerUIStrings('ui/RemoteDebuggingTerminatedScreen.js', UIStrings);
+const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
 export class RemoteDebuggingTerminatedScreen extends VBox {
   /**
    * @param {string} reason
@@ -19,9 +31,8 @@
     const reasonElement = message.createChild('span', 'reason');
     reasonElement.textContent = reason;
     message.appendChild(formatLocalized('Debugging connection was closed. Reason: %s', [reasonElement]));
-    this.contentElement.createChild('div', 'message').textContent =
-        Common.UIString.UIString('Reconnect when ready by reopening DevTools.');
-    const button = createTextButton(Common.UIString.UIString('Reconnect DevTools'), () => window.location.reload());
+    this.contentElement.createChild('div', 'message').textContent = i18nString(UIStrings.reconnectWhenReadyByReopening);
+    const button = createTextButton(i18nString(UIStrings.reconnectDevtools), () => window.location.reload());
     this.contentElement.createChild('div', 'button').appendChild(button);
   }
 
diff --git a/front_end/ui/SearchableView.js b/front_end/ui/SearchableView.js
index 3642f33..4cd2007 100644
--- a/front_end/ui/SearchableView.js
+++ b/front_end/ui/SearchableView.js
@@ -30,6 +30,7 @@
  */
 
 import * as Common from '../common/common.js';
+import * as i18n from '../i18n/i18n.js';
 
 import * as ARIAUtils from './ARIAUtils.js';
 import {HistoryInput} from './HistoryInput.js';
@@ -39,6 +40,57 @@
 import {createTextButton} from './UIUtils.js';
 import {VBox} from './Widget.js';
 
+export const UIStrings = {
+  /**
+  *@description Text on a button to replace one instance with input text for the ctrl+F search bar
+  */
+  replace: 'Replace',
+  /**
+  *@description Text to find an item
+  */
+  findString: 'Find',
+  /**
+  *@description Text on a button to search previous instance for the ctrl+F search bar
+  */
+  searchPrevious: 'Search previous',
+  /**
+  *@description Text on a button to search next instance for the ctrl+F search bar
+  */
+  searchNext: 'Search next',
+  /**
+  *@description Text to search by matching case of the input
+  */
+  matchCase: 'Match Case',
+  /**
+  *@description Text for searching with regular expressinn
+  */
+  useRegularExpression: 'Use Regular Expression',
+  /**
+  *@description Text to cancel something
+  */
+  cancel: 'Cancel',
+  /**
+  *@description Text on a button to replace all instances with input text for the ctrl+F search bar
+  */
+  replaceAll: 'Replace all',
+  /**
+  *@description Text to indicate the current match index and the total number of matches for the ctrl+F search bar
+  *@example {2} PH1
+  *@example {3} PH2
+  */
+  dOfD: '{PH1} of {PH2}',
+  /**
+  *@description Text to indicate search result for the ctrl+F search bar
+  */
+  matchString: '1 match',
+  /**
+  *@description Text to indicate search result for the ctrl+F search bar
+  *@example {2} PH1
+  */
+  dMatches: '{PH1} matches',
+};
+const str_ = i18n.i18n.registerUIStrings('ui/SearchableView.js', UIStrings);
+const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
 export class SearchableView extends VBox {
   /**
    * @param {!Searchable} searchable
@@ -61,7 +113,7 @@
     this._footerElement = this._footerElementContainer.createChild('div', 'toolbar-search');
 
     const replaceToggleToolbar = new Toolbar('replace-toggle-toolbar', this._footerElement);
-    this._replaceToggleButton = new ToolbarToggle(Common.UIString.UIString('Replace'), 'mediumicon-replace');
+    this._replaceToggleButton = new ToolbarToggle(i18nString(UIStrings.replace), 'mediumicon-replace');
     this._replaceToggleButton.addEventListener(ToolbarButton.Events.Click, this._toggleReplace, this);
     replaceToggleToolbar.appendToolbarItem(this._replaceToggleButton);
 
@@ -72,7 +124,7 @@
     this._searchInputElement.type = 'search';
     this._searchInputElement.classList.add('search-replace', 'custom-search-input');
     this._searchInputElement.id = 'search-input-field';
-    this._searchInputElement.placeholder = Common.UIString.UIString('Find');
+    this._searchInputElement.placeholder = i18nString(UIStrings.findString);
     searchControlElement.appendChild(this._searchInputElement);
 
     this._matchesElement = searchControlElement.createChild('label', 'search-results-matches');
@@ -83,14 +135,14 @@
     this._searchNavigationPrevElement =
         searchNavigationElement.createChild('div', 'toolbar-search-navigation toolbar-search-navigation-prev');
     this._searchNavigationPrevElement.addEventListener('click', this._onPrevButtonSearch.bind(this), false);
-    Tooltip.install(this._searchNavigationPrevElement, Common.UIString.UIString('Search previous'));
-    ARIAUtils.setAccessibleName(this._searchNavigationPrevElement, Common.UIString.UIString('Search previous'));
+    Tooltip.install(this._searchNavigationPrevElement, i18nString(UIStrings.searchPrevious));
+    ARIAUtils.setAccessibleName(this._searchNavigationPrevElement, i18nString(UIStrings.searchPrevious));
 
     this._searchNavigationNextElement =
         searchNavigationElement.createChild('div', 'toolbar-search-navigation toolbar-search-navigation-next');
     this._searchNavigationNextElement.addEventListener('click', this._onNextButtonSearch.bind(this), false);
-    Tooltip.install(this._searchNavigationNextElement, Common.UIString.UIString('Search next'));
-    ARIAUtils.setAccessibleName(this._searchNavigationNextElement, Common.UIString.UIString('Search next'));
+    Tooltip.install(this._searchNavigationNextElement, i18nString(UIStrings.searchNext));
+    ARIAUtils.setAccessibleName(this._searchNavigationNextElement, i18nString(UIStrings.searchNext));
 
     this._searchInputElement.addEventListener('keydown', this._onSearchKeyDown.bind(this), true);
     this._searchInputElement.addEventListener('input', this._onInput.bind(this), false);
@@ -100,7 +152,7 @@
         /** @type {!HTMLInputElement} */ (
             searchInputElements.createChild('input', 'search-replace toolbar-replace-control hidden'));
     this._replaceInputElement.addEventListener('keydown', this._onReplaceKeyDown.bind(this), true);
-    this._replaceInputElement.placeholder = Common.UIString.UIString('Replace');
+    this._replaceInputElement.placeholder = i18nString(UIStrings.replace);
 
     this._buttonsContainer = this._footerElement.createChild('div', 'toolbar-search-buttons');
     const firstRowButtons = this._buttonsContainer.createChild('div', 'first-row-buttons');
@@ -108,32 +160,32 @@
     const toolbar = new Toolbar('toolbar-search-options', firstRowButtons);
 
     if (this._searchProvider.supportsCaseSensitiveSearch()) {
-      this._caseSensitiveButton = new ToolbarToggle(Common.UIString.UIString('Match Case'));
+      this._caseSensitiveButton = new ToolbarToggle(i18nString(UIStrings.matchCase));
       this._caseSensitiveButton.setText('Aa');
       this._caseSensitiveButton.addEventListener(ToolbarButton.Events.Click, this._toggleCaseSensitiveSearch, this);
       toolbar.appendToolbarItem(this._caseSensitiveButton);
     }
 
     if (this._searchProvider.supportsRegexSearch()) {
-      this._regexButton = new ToolbarToggle(Common.UIString.UIString('Use Regular Expression'));
+      this._regexButton = new ToolbarToggle(i18nString(UIStrings.useRegularExpression));
       this._regexButton.setText('.*');
       this._regexButton.addEventListener(ToolbarButton.Events.Click, this._toggleRegexSearch, this);
       toolbar.appendToolbarItem(this._regexButton);
     }
 
     const cancelButtonElement =
-        createTextButton(Common.UIString.UIString('Cancel'), this.closeSearch.bind(this), 'search-action-button');
+        createTextButton(i18nString(UIStrings.cancel), this.closeSearch.bind(this), 'search-action-button');
     firstRowButtons.appendChild(cancelButtonElement);
 
     this._secondRowButtons = this._buttonsContainer.createChild('div', 'second-row-buttons hidden');
 
     this._replaceButtonElement =
-        createTextButton(Common.UIString.UIString('Replace'), this._replace.bind(this), 'search-action-button');
+        createTextButton(i18nString(UIStrings.replace), this._replace.bind(this), 'search-action-button');
     this._replaceButtonElement.disabled = true;
     this._secondRowButtons.appendChild(this._replaceButtonElement);
 
     this._replaceAllButtonElement =
-        createTextButton(Common.UIString.UIString('Replace all'), this._replaceAll.bind(this), 'search-action-button');
+        createTextButton(i18nString(UIStrings.replaceAll), this._replaceAll.bind(this), 'search-action-button');
     this._secondRowButtons.appendChild(this._replaceAllButtonElement);
     this._replaceAllButtonElement.disabled = true;
 
@@ -347,11 +399,11 @@
     if (!this._currentQuery) {
       this._matchesElement.textContent = '';
     } else if (matches === 0 || currentMatchIndex >= 0) {
-      this._matchesElement.textContent = Common.UIString.UIString('%d of %d', currentMatchIndex + 1, matches);
+      this._matchesElement.textContent = i18nString(UIStrings.dOfD, {PH1: currentMatchIndex + 1, PH2: matches});
     } else if (matches === 1) {
-      this._matchesElement.textContent = Common.UIString.UIString('1 match');
+      this._matchesElement.textContent = i18nString(UIStrings.matchString);
     } else {
-      this._matchesElement.textContent = Common.UIString.UIString('%d matches', matches);
+      this._matchesElement.textContent = i18nString(UIStrings.dMatches, {PH1: matches});
     }
     this._updateSearchNavigationButtonState(matches > 0);
   }
diff --git a/front_end/ui/SettingsUI.js b/front_end/ui/SettingsUI.js
index d6a77a9..4089d9b 100644
--- a/front_end/ui/SettingsUI.js
+++ b/front_end/ui/SettingsUI.js
@@ -29,7 +29,7 @@
  */
 
 import * as Common from '../common/common.js';
-import {ls} from '../platform/platform.js';
+import * as i18n from '../i18n/i18n.js';
 import * as Root from '../root/root.js';
 
 import * as ARIAUtils from './ARIAUtils.js';
@@ -37,6 +37,19 @@
 import {Tooltip} from './Tooltip.js';
 import {CheckboxLabel} from './UIUtils.js';
 
+export const UIStrings = {
+  /**
+  *@description Note when a setting change will require the user to reload DevTools
+  *@example {*} PH1
+  */
+  srequiresReload: '{PH1}Requires reload',
+  /**
+  *@description Message to display if a setting change requires a reload of DevTools
+  */
+  oneOrMoreSettingsHaveChanged: 'One or more settings have changed which requires a reload to take effect.',
+};
+const str_ = i18n.i18n.registerUIStrings('ui/SettingsUI.js', UIStrings);
+const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
 /**
  * @param {string} name
  * @param {!Common.Settings.Setting<boolean>} setting
@@ -92,7 +105,7 @@
   let reloadWarning = /** @type {?Element} */ (null);
   if (requiresReload) {
     reloadWarning = settingSelectElement.createChild('span', 'reload-warning hidden');
-    reloadWarning.textContent = ls`${'*'}Requires reload`;
+    reloadWarning.textContent = i18nString(UIStrings.srequiresReload, {PH1: '*'});
     ARIAUtils.markAsAlert(reloadWarning);
   }
 
@@ -115,8 +128,7 @@
     setting.set(options[select.selectedIndex].value);
     if (reloadWarning) {
       reloadWarning.classList.remove('hidden');
-      InspectorView.instance().displayReloadRequiredWarning(
-          ls`One or more settings have changed which requires a reload to take effect.`);
+      InspectorView.instance().displayReloadRequiredWarning(i18nString(UIStrings.oneOrMoreSettingsHaveChanged));
     }
   }
 };
diff --git a/front_end/ui/SoftContextMenu.js b/front_end/ui/SoftContextMenu.js
index 4640ec2..d08cb44 100644
--- a/front_end/ui/SoftContextMenu.js
+++ b/front_end/ui/SoftContextMenu.js
@@ -29,7 +29,7 @@
  */
 
 import * as Host from '../host/host.js';
-import {ls} from '../platform/platform.js';
+import * as i18n from '../i18n/i18n.js';
 import * as ThemeSupport from '../theme_support/theme_support.js';
 
 import * as ARIAUtils from './ARIAUtils.js';
@@ -37,6 +37,31 @@
 import {Icon} from './Icon.js';
 import {createTextChild, ElementFocusRestorer} from './UIUtils.js';
 
+export const UIStrings = {
+  /**
+  *@description Text exposed to screen readers on checked items.
+  */
+  checked: 'checked',
+  /**
+  *@description Text exposed to screen readers on unchecked items.
+  */
+  unchecked: 'unchecked',
+  /**
+  *@description Accessibility label for checkable SoftContextMenuItems with shortcuts
+  *@example {Open File} PH1
+  *@example {Ctrl + P} PH2
+  *@example {checked} PH3
+  */
+  sSS: '{PH1}, {PH2}, {PH3}',
+  /**
+  *@description Generic text with two placeholders separated by a comma
+  *@example {1 613 680} PH1
+  *@example {44 %} PH2
+  */
+  sS: '{PH1}, {PH2}',
+};
+const str_ = i18n.i18n.registerUIStrings('ui/SoftContextMenu.js', UIStrings);
+const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
 export class SoftContextMenu {
   /**
    * @param {!Array.<!SoftContextMenuDescriptor>} items
@@ -199,14 +224,14 @@
     let accessibleName = item.label || '';
 
     if (item.type === 'checkbox') {
-      const checkedState = item.checked ? ls`checked` : ls`unchecked`;
+      const checkedState = item.checked ? i18nString(UIStrings.checked) : i18nString(UIStrings.unchecked);
       if (item.shortcut) {
-        accessibleName = ls`${item.label}, ${item.shortcut}, ${checkedState}`;
+        accessibleName = i18nString(UIStrings.sSS, {PH1: item.label, PH2: item.shortcut, PH3: checkedState});
       } else {
-        accessibleName = ls`${item.label}, ${checkedState}`;
+        accessibleName = i18nString(UIStrings.sS, {PH1: item.label, PH2: checkedState});
       }
     } else if (item.shortcut) {
-      accessibleName = ls`${item.label}, ${item.shortcut}`;
+      accessibleName = i18nString(UIStrings.sS, {PH1: item.label, PH2: item.shortcut});
     }
     ARIAUtils.setAccessibleName(menuItemElement, accessibleName);
 
diff --git a/front_end/ui/SoftDropDown.js b/front_end/ui/SoftDropDown.js
index 00d2c54..5bd9991 100644
--- a/front_end/ui/SoftDropDown.js
+++ b/front_end/ui/SoftDropDown.js
@@ -2,9 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import * as Common from '../common/common.js';        // eslint-disable-line no-unused-vars
+import * as Common from '../common/common.js';  // eslint-disable-line no-unused-vars
+import * as i18n from '../i18n/i18n.js';
 import * as Platform from '../platform/platform.js';  // eslint-disable-line no-unused-vars
-import {ls} from '../platform/platform.js';
 
 import * as ARIAUtils from './ARIAUtils.js';
 import {Size} from './Geometry.js';
@@ -15,6 +15,14 @@
 import {appendStyle} from './utils/append-style.js';
 import {createShadowRootWithCoreStyles} from './utils/create-shadow-root-with-core-styles.js';
 
+export const UIStrings = {
+  /**
+  *@description Placeholder text in Soft Drop Down
+  */
+  noItemSelected: '(no item selected)',
+};
+const str_ = i18n.i18n.registerUIStrings('ui/SoftDropDown.js', UIStrings);
+const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
 /**
  * @template T
  * @implements {ListDelegate<T>}
@@ -29,7 +37,7 @@
     this._selectedItem = null;
     this._model = model;
 
-    this._placeholderText = ls`(no item selected)`;
+    this._placeholderText = i18nString(UIStrings.noItemSelected);
 
     this.element = document.createElement('button');
     this.element.classList.add('soft-dropdown');
diff --git a/front_end/ui/SplitWidget.js b/front_end/ui/SplitWidget.js
index 5d3b53e..2e4b33e 100644
--- a/front_end/ui/SplitWidget.js
+++ b/front_end/ui/SplitWidget.js
@@ -29,6 +29,7 @@
  */
 
 import * as Common from '../common/common.js';
+import * as i18n from '../i18n/i18n.js';
 import * as Platform from '../platform/platform.js';
 
 import {Constraints} from './Geometry.js';
@@ -37,6 +38,20 @@
 import {Widget} from './Widget.js';
 import {Events as ZoomManagerEvents, ZoomManager} from './ZoomManager.js';
 
+export const UIStrings = {
+  /**
+  *@description Text to show a tool or panel
+  *@example {Audits} PH1
+  */
+  showS: 'Show {PH1}',
+  /**
+  *@description Text on a button to hide sidebar
+  *@example {Setting} PH1
+  */
+  hideS: 'Hide {PH1}',
+};
+const str_ = i18n.i18n.registerUIStrings('ui/SplitWidget.js', UIStrings);
+const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
 
 export class SplitWidget extends Widget {
   /**
@@ -981,7 +996,9 @@
           (this.isSidebarSecond() ? 'largeicon-hide-bottom-sidebar' : 'largeicon-hide-top-sidebar');
     }
     this._showHideSidebarButton.setGlyph(glyph);
-    this._showHideSidebarButton.setTitle(sidebarHidden ? this._showSidebarButtonTitle : this._hideSidebarButtonTitle);
+    this._showHideSidebarButton.setTitle(
+        sidebarHidden ? i18nString(UIStrings.showS, {PH1: this._showSidebarButtonTitle}) :
+                        i18nString(UIStrings.hideS, {PH1: this._hideSidebarButtonTitle}));
   }
 }
 
diff --git a/front_end/ui/SuggestBox.js b/front_end/ui/SuggestBox.js
index 1d17e39..3e8f3db 100644
--- a/front_end/ui/SuggestBox.js
+++ b/front_end/ui/SuggestBox.js
@@ -28,8 +28,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import * as i18n from '../i18n/i18n.js';
 import * as Platform from '../platform/platform.js';
-import {ls} from '../platform/platform.js';
 import * as TextUtils from '../text_utils/text_utils.js';  // eslint-disable-line no-unused-vars
 
 import * as ARIAUtils from './ARIAUtils.js';
@@ -42,6 +42,17 @@
 import {createShadowRootWithCoreStyles} from './utils/create-shadow-root-with-core-styles.js';
 import {measuredScrollbarWidth} from './utils/measured-scrollbar-width.js';
 
+export const UIStrings = {
+  /**
+  *@description Aria alert to read the suggestion for the suggestion box when typing in text editor
+  *@example {name} PH1
+  *@example {2} PH2
+  *@example {5} PH3
+  */
+  sSuggestionSOfS: '{PH1}, suggestion {PH2} of {PH3}',
+};
+const str_ = i18n.i18n.registerUIStrings('ui/SuggestBox.js', UIStrings);
+const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
 /**
  * @interface
  */
@@ -174,7 +185,9 @@
   _applySuggestion(isIntermediateSuggestion) {
     if (this._onlyCompletion) {
       ARIAUtils.alert(
-          ls`${this._onlyCompletion.text}, suggestion ${this._list.selectedIndex() + 1} of ${this._items.length}`,
+          i18nString(
+              UIStrings.sSuggestionSOfS,
+              {PH1: this._onlyCompletion.text, PH2: this._list.selectedIndex() + 1, PH3: this._items.length}),
           this._element);
       this._suggestBoxDelegate.applySuggestion(this._onlyCompletion, isIntermediateSuggestion);
       return true;
@@ -182,8 +195,9 @@
     const suggestion = this._list.selectedItem();
     if (suggestion && suggestion.text) {
       ARIAUtils.alert(
-          ls`${suggestion.title || suggestion.text}, suggestion ${this._list.selectedIndex() + 1} of ${
-              this._items.length}`,
+          i18nString(
+              UIStrings.sSuggestionSOfS,
+              {PH1: suggestion.title || suggestion.text, PH2: this._list.selectedIndex() + 1, PH3: this._items.length}),
           this._element);
     }
     this._suggestBoxDelegate.applySuggestion(suggestion, isIntermediateSuggestion);
diff --git a/front_end/ui/TabbedPane.js b/front_end/ui/TabbedPane.js
index 5da8ace..1a0b8a6 100644
--- a/front_end/ui/TabbedPane.js
+++ b/front_end/ui/TabbedPane.js
@@ -28,9 +28,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import * as Common from '../common/common.js';
+import * as Common from '../common/common.js';  // eslint-disable-line no-unused-vars
+import * as i18n from '../i18n/i18n.js';
 import * as Platform from '../platform/platform.js';
-import {ls} from '../platform/platform.js';
 
 import * as ARIAUtils from './ARIAUtils.js';
 import {ContextMenu} from './ContextMenu.js';
@@ -42,6 +42,35 @@
 import {VBox, Widget} from './Widget.js';  // eslint-disable-line no-unused-vars
 import {Events as ZoomManagerEvents, ZoomManager} from './ZoomManager.js';
 
+export const UIStrings = {
+  /**
+  *@description The aria label for the button to open more tabs at the right tabbed pane in Elements tools
+  */
+  moreTabs: 'More tabs',
+  /**
+  *@description Text in Tabbed Pane
+  *@example {tab} PH1
+  */
+  closeS: 'Close {PH1}',
+  /**
+  *@description Text to close something
+  */
+  close: 'Close',
+  /**
+  *@description Text on a menu option to close other drawers when right click on a drawer title
+  */
+  closeOthers: 'Close others',
+  /**
+  *@description Text on a menu option to close the drawer to the right when right click on a drawer title
+  */
+  closeTabsToTheRight: 'Close tabs to the right',
+  /**
+  *@description Text on a menu option to close all the drawers except Console when right click on a drawer title
+  */
+  closeAll: 'Close all',
+};
+const str_ = i18n.i18n.registerUIStrings('ui/TabbedPane.js', UIStrings);
+const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
 export class TabbedPane extends VBox {
   constructor() {
     super(true);
@@ -643,7 +672,7 @@
     dropDownContainer.classList.add('tabbed-pane-header-tabs-drop-down-container');
     const chevronIcon = Icon.create('largeicon-chevron', 'chevron-icon');
     ARIAUtils.markAsMenuButton(dropDownContainer);
-    ARIAUtils.setAccessibleName(dropDownContainer, ls`More tabs`);
+    ARIAUtils.setAccessibleName(dropDownContainer, i18nString(UIStrings.moreTabs));
     dropDownContainer.tabIndex = 0;
     dropDownContainer.appendChild(chevronIcon);
     dropDownContainer.addEventListener('click', this._dropDownClicked.bind(this));
@@ -1270,7 +1299,7 @@
       // @ts-ignore dt-close-button custom element has a `gray` attribute.
       closeButton.gray = true;
       // @ts-ignore dt-close-button custom element has its own custom `setAccessibleName`.
-      closeButton.setAccessibleName(ls`Close ${this.title}`);
+      closeButton.setAccessibleName(i18nString(UIStrings.closeS, {PH1: this.title}));
       tabElement.classList.add('closeable');
     }
 
@@ -1375,11 +1404,10 @@
 
     const contextMenu = new ContextMenu(event);
     if (this._closeable) {
-      contextMenu.defaultSection().appendItem(Common.UIString.UIString('Close'), close.bind(this));
-      contextMenu.defaultSection().appendItem(Common.UIString.UIString('Close others'), closeOthers.bind(this));
-      contextMenu.defaultSection().appendItem(
-          Common.UIString.UIString('Close tabs to the right'), closeToTheRight.bind(this));
-      contextMenu.defaultSection().appendItem(Common.UIString.UIString('Close all'), closeAll.bind(this));
+      contextMenu.defaultSection().appendItem(i18nString(UIStrings.close), close.bind(this));
+      contextMenu.defaultSection().appendItem(i18nString(UIStrings.closeOthers), closeOthers.bind(this));
+      contextMenu.defaultSection().appendItem(i18nString(UIStrings.closeTabsToTheRight), closeToTheRight.bind(this));
+      contextMenu.defaultSection().appendItem(i18nString(UIStrings.closeAll), closeAll.bind(this));
     }
     if (this._delegate) {
       this._delegate.onContextMenu(this.id, contextMenu);
diff --git a/front_end/ui/TargetCrashedScreen.js b/front_end/ui/TargetCrashedScreen.js
index d2df06e..13f3179 100644
--- a/front_end/ui/TargetCrashedScreen.js
+++ b/front_end/ui/TargetCrashedScreen.js
@@ -2,9 +2,22 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import * as Common from '../common/common.js';
+import * as i18n from '../i18n/i18n.js';
+
 import {VBox} from './Widget.js';
 
+export const UIStrings = {
+  /**
+  *@description Text in dialog box when the target page crashed
+  */
+  devtoolsWasDisconnectedFromThe: 'DevTools was disconnected from the page.',
+  /**
+  *@description Text content of content element
+  */
+  oncePageIsReloadedDevtoolsWill: 'Once page is reloaded, DevTools will automatically reconnect.',
+};
+const str_ = i18n.i18n.registerUIStrings('ui/TargetCrashedScreen.js', UIStrings);
+const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
 export class TargetCrashedScreen extends VBox {
   /**
    * @param {function():*} hideCallback
@@ -13,9 +26,9 @@
     super(true);
     this.registerRequiredCSS('ui/targetCrashedScreen.css', {enableLegacyPatching: false});
     this.contentElement.createChild('div', 'message').textContent =
-        Common.UIString.UIString('DevTools was disconnected from the page.');
+        i18nString(UIStrings.devtoolsWasDisconnectedFromThe);
     this.contentElement.createChild('div', 'message').textContent =
-        Common.UIString.UIString('Once page is reloaded, DevTools will automatically reconnect.');
+        i18nString(UIStrings.oncePageIsReloadedDevtoolsWill);
     this._hideCallback = hideCallback;
   }
 
diff --git a/front_end/ui/UIUtils.js b/front_end/ui/UIUtils.js
index 4431ba9..3b287d5 100644
--- a/front_end/ui/UIUtils.js
+++ b/front_end/ui/UIUtils.js
@@ -32,8 +32,8 @@
 import * as Common from '../common/common.js';
 import * as DOMExtension from '../dom_extension/dom_extension.js';
 import * as Host from '../host/host.js';
+import * as i18n from '../i18n/i18n.js';
 import * as Platform from '../platform/platform.js';
-import {ls} from '../platform/platform.js';
 import * as TextUtils from '../text_utils/text_utils.js';
 import * as ThemeSupport from '../theme_support/theme_support.js';
 
@@ -53,6 +53,89 @@
 import {measuredScrollbarWidth} from './utils/measured-scrollbar-width.js';
 import {registerCustomElement} from './utils/register-custom-element.js';
 
+export const UIStrings = {
+  /**
+  *@description Micros format in UIUtils
+  *@example {2} PH1
+  */
+  fmms: '{PH1} μs',
+  /**
+  *@description Sub millis format in UIUtils
+  *@example {2.14} PH1
+  */
+  fms: '{PH1} ms',
+  /**
+  *@description Seconds format in UIUtils
+  *@example {2.14} PH1
+  */
+  fs: '{PH1} s',
+  /**
+  *@description Minutes format in UIUtils
+  *@example {2.2} PH1
+  */
+  fmin: '{PH1} min',
+  /**
+  *@description Hours format in UIUtils
+  *@example {2.2} PH1
+  */
+  fhrs: '{PH1} hrs',
+  /**
+  *@description Days format in UIUtils
+  *@example {2.2} PH1
+  */
+  fdays: '{PH1} days',
+  /**
+  *@description label to open link externally
+  */
+  openInNewTab: 'Open in new tab',
+  /**
+  *@description label to copy link address
+  */
+  copyLinkAddress: 'Copy link address',
+  /**
+  *@description label to copy file name
+  */
+  copyFileName: 'Copy file name',
+  /**
+  *@description label for the profiler control button
+  */
+  anotherProfilerIsAlreadyActive: 'Another profiler is already active',
+  /**
+  *@description Text in UIUtils
+  */
+  promiseResolvedAsync: 'Promise resolved (async)',
+  /**
+  *@description Text in UIUtils
+  */
+  promiseRejectedAsync: 'Promise rejected (async)',
+  /**
+  *@description Text in UIUtils
+  *@example {Promise} PH1
+  */
+  sAsync: '{PH1} (async)',
+  /**
+  *@description Text for the title of asynchronous function calls group in Call Stack
+  */
+  asyncCall: 'Async Call',
+  /**
+  *@description Text for the name of anonymous functions
+  */
+  anonymous: '(anonymous)',
+  /**
+  *@description Text to close something
+  */
+  close: 'Close',
+  /**
+  *@description Text on a button for message dialog
+  */
+  ok: 'OK',
+  /**
+  *@description Text to cancel something
+  */
+  cancel: 'Cancel',
+};
+const str_ = i18n.i18n.registerUIStrings('ui/UIUtils.js', UIStrings);
+const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
 export const highlightedSearchResultClassName = 'highlighted-search-result';
 export const highlightedCurrentSearchResultClassName = 'current-search-result';
 
@@ -593,31 +676,9 @@
  */
 Number.preciseMillisToString = function(ms, precision) {
   precision = precision || 0;
-  const format = '%.' + precision + 'f\xa0ms';
-  return Common.UIString.UIString(format, ms);
+  return i18nString(UIStrings.fms, {PH1: ms.toFixed(precision)});
 };
 
-/** @type {!Common.UIString.UIStringFormat} */
-export const _microsFormat = new Common.UIString.UIStringFormat('%.0f\xa0\u03bcs');
-
-/** @type {!Common.UIString.UIStringFormat} */
-export const _subMillisFormat = new Common.UIString.UIStringFormat('%.2f\xa0ms');
-
-/** @type {!Common.UIString.UIStringFormat} */
-export const _millisFormat = new Common.UIString.UIStringFormat('%.0f\xa0ms');
-
-/** @type {!Common.UIString.UIStringFormat} */
-export const _secondsFormat = new Common.UIString.UIStringFormat('%.2f\xa0s');
-
-/** @type {!Common.UIString.UIStringFormat} */
-export const _minutesFormat = new Common.UIString.UIStringFormat('%.1f\xa0min');
-
-/** @type {!Common.UIString.UIStringFormat} */
-export const _hoursFormat = new Common.UIString.UIStringFormat('%.1f\xa0hrs');
-
-/** @type {!Common.UIString.UIStringFormat} */
-export const _daysFormat = new Common.UIString.UIStringFormat('%.1f\xa0days');
-
 /**
  * @param {number} ms
  * @param {boolean=} higherResolution
@@ -633,32 +694,32 @@
   }
 
   if (higherResolution && ms < 0.1) {
-    return _microsFormat.format(ms * 1000);
+    return i18nString(UIStrings.fmms, {PH1: (ms * 1000).toFixed(0)});
   }
   if (higherResolution && ms < 1000) {
-    return _subMillisFormat.format(ms);
+    return i18nString(UIStrings.fms, {PH1: (ms).toFixed(2)});
   }
   if (ms < 1000) {
-    return _millisFormat.format(ms);
+    return i18nString(UIStrings.fms, {PH1: (ms).toFixed(0)});
   }
 
   const seconds = ms / 1000;
   if (seconds < 60) {
-    return _secondsFormat.format(seconds);
+    return i18nString(UIStrings.fs, {PH1: (seconds).toFixed(2)});
   }
 
   const minutes = seconds / 60;
   if (minutes < 60) {
-    return _minutesFormat.format(minutes);
+    return i18nString(UIStrings.fmin, {PH1: (minutes).toFixed(1)});
   }
 
   const hours = minutes / 60;
   if (hours < 24) {
-    return _hoursFormat.format(hours);
+    return i18nString(UIStrings.fhrs, {PH1: (hours).toFixed(1)});
   }
 
   const days = hours / 24;
-  return _daysFormat.format(days);
+  return i18nString(UIStrings.fdays, {PH1: (days).toFixed(1)});
 };
 
 /**
@@ -702,8 +763,7 @@
     a.appendChild(typeof b === 'string' ? document.createTextNode(b) : /** @type {!Element} */ (b));
     return a;
   }
-  return Platform.StringUtilities
-      .format(Common.UIString.UIString(format), substitutions, formatters, document.createElement('span'), append)
+  return Platform.StringUtilities.format(format, substitutions, formatters, document.createElement('span'), append)
       .formattedResult;
 }
 
@@ -711,14 +771,14 @@
  * @return {string}
  */
 export function openLinkExternallyLabel() {
-  return Common.UIString.UIString('Open in new tab');
+  return i18nString(UIStrings.openInNewTab);
 }
 
 /**
  * @return {string}
  */
 export function copyLinkAddressLabel() {
-  return Common.UIString.UIString('Copy link address');
+  return i18nString(UIStrings.copyLinkAddress);
 }
 
 
@@ -726,14 +786,14 @@
  * @return {string}
  */
 export function copyFileNameLabel() {
-  return ls`Copy file name`;
+  return i18nString(UIStrings.copyFileName);
 }
 
 /**
  * @return {string}
  */
 export function anotherProfilerActiveLabel() {
-  return Common.UIString.UIString('Another profiler is already active');
+  return i18nString(UIStrings.anotherProfilerIsAlreadyActive);
 }
 
 /**
@@ -743,14 +803,14 @@
 export function asyncStackTraceLabel(description) {
   if (description) {
     if (description === 'Promise.resolve') {
-      return ls`Promise resolved (async)`;
+      return i18nString(UIStrings.promiseResolvedAsync);
     }
     if (description === 'Promise.reject') {
-      return ls`Promise rejected (async)`;
+      return i18nString(UIStrings.promiseRejectedAsync);
     }
-    return ls`${description} (async)`;
+    return i18nString(UIStrings.sAsync, {PH1: description});
   }
-  return Common.UIString.UIString('Async Call');
+  return i18nString(UIStrings.asyncCall);
 }
 
 /**
@@ -1276,7 +1336,7 @@
  * @return {string}
  */
 export function beautifyFunctionName(name) {
-  return name || Common.UIString.UIString('(anonymous)');
+  return name || i18nString(UIStrings.anonymous);
 }
 
 /**
@@ -1624,7 +1684,7 @@
         this, {cssFile: 'ui/closeButton.css', enableLegacyPatching: false, delegatesFocus: undefined});
     /** @type {!HTMLElement} */
     this._buttonElement = /** @type {!HTMLElement} */ (root.createChild('div', 'close-button'));
-    ARIAUtils.setAccessibleName(this._buttonElement, ls`Close`);
+    ARIAUtils.setAccessibleName(this._buttonElement, i18nString(UIStrings.close));
     ARIAUtils.markAsButton(this._buttonElement);
     const regularIcon = Icon.create('smallicon-cross', 'default-icon');
     this._hoverIcon = Icon.create('mediumicon-red-cross-hover', 'hover-icon');
@@ -1920,7 +1980,7 @@
         {cssFile: 'ui/confirmDialog.css', enableLegacyPatching: false, delegatesFocus: undefined});
     const content = shadowRoot.createChild('div', 'widget');
     await new Promise(resolve => {
-      const okButton = createTextButton(Common.UIString.UIString('OK'), resolve, '', true);
+      const okButton = createTextButton(i18nString(UIStrings.ok), resolve, '', true);
       content.createChild('div', 'message').createChild('span').textContent = message;
       content.createChild('div', 'button').appendChild(okButton);
       dialog.setOutsideClickCallback(event => {
@@ -1953,9 +2013,10 @@
     const buttonsBar = content.createChild('div', 'button');
     const result = await new Promise(resolve => {
       const okButton = createTextButton(
-          /* text= */ ls`OK`, /* clickHandler= */ () => resolve(true), /* className= */ '', /* primary= */ true);
+          /* text= */ i18nString(UIStrings.ok), /* clickHandler= */ () => resolve(true), /* className= */ '',
+          /* primary= */ true);
       buttonsBar.appendChild(okButton);
-      buttonsBar.appendChild(createTextButton(ls`Cancel`, () => resolve(false)));
+      buttonsBar.appendChild(createTextButton(i18nString(UIStrings.cancel), () => resolve(false)));
       dialog.setOutsideClickCallback(event => {
         event.consume();
         resolve(false);
diff --git a/front_end/ui/ViewManager.js b/front_end/ui/ViewManager.js
index 7f1a103..8604160 100644
--- a/front_end/ui/ViewManager.js
+++ b/front_end/ui/ViewManager.js
@@ -4,7 +4,7 @@
 
 import * as Common from '../common/common.js';
 import * as Host from '../host/host.js';
-import {ls} from '../platform/platform.js';
+import * as i18n from '../i18n/i18n.js';
 
 import * as ARIAUtils from './ARIAUtils.js';
 import {ContextMenu} from './ContextMenu.js';  // eslint-disable-line no-unused-vars
@@ -16,6 +16,15 @@
 import {getRegisteredLocationResolvers, getRegisteredViewExtensions, registerLocationResolver, registerViewExtension, ViewLocationCategoryValues, ViewLocationValues, ViewPersistence, ViewRegistration} from './ViewRegistration.js';
 import {VBox, Widget} from './Widget.js';  // eslint-disable-line no-unused-vars
 
+export const UIStrings = {
+  /**
+  *@description Aria label for the tab panel view container
+  *@example {Sensors} PH1
+  */
+  sPanel: '{PH1} panel',
+};
+const str_ = i18n.i18n.registerUIStrings('ui/ViewManager.js', UIStrings);
+const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
 /**
  * @implements {View}
  */
@@ -415,7 +424,7 @@
     this._view = view;
     this.element.tabIndex = -1;
     ARIAUtils.markAsTabpanel(this.element);
-    ARIAUtils.setAccessibleName(this.element, ls`${view.title()} panel`);
+    ARIAUtils.setAccessibleName(this.element, i18nString(UIStrings.sPanel, {PH1: view.title()}));
     this.setDefaultFocusedElement(this.element);
   }
 
diff --git a/front_end/ui/ViewRegistration.ts b/front_end/ui/ViewRegistration.ts
index 4a8a536..7f82789 100644
--- a/front_end/ui/ViewRegistration.ts
+++ b/front_end/ui/ViewRegistration.ts
@@ -1,8 +1,8 @@
+
 // Copyright 2020 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 import * as Platform from '../platform/platform.js';
-import {ls} from '../platform/platform.js';
 import * as Root from '../root/root.js';
 
 import type {ViewLocationResolver} from './View.js';
@@ -146,14 +146,15 @@
   return registeredLocationResolvers;
 }
 
+// TODO(crbug.com/1181019)
 export const ViewLocationCategoryValues = {
-  ELEMENTS: ls`Elements`,
-  DRAWER: ls`Drawer`,
-  DRAWER_SIDEBAR: ls`Drawer sidebar`,
-  PANEL: ls`Panel`,
-  NETWORK: ls`Network`,
-  SETTINGS: ls`Settings`,
-  SOURCES: ls`Sources`,
+  ELEMENTS: 'Elements',
+  DRAWER: 'Drawer',
+  DRAWER_SIDEBAR: 'Drawer sidebar',
+  PANEL: 'Panel',
+  NETWORK: 'Network',
+  SETTINGS: 'Settings',
+  SOURCES: 'Sources',
 };
 
 type ViewLocationCategory = typeof ViewLocationCategoryValues[keyof typeof ViewLocationCategoryValues];
diff --git a/front_end/ui/components/DataGrid.ts b/front_end/ui/components/DataGrid.ts
index 6e57a00..c6aa69f 100644
--- a/front_end/ui/components/DataGrid.ts
+++ b/front_end/ui/components/DataGrid.ts
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import * as Common from '../../common/common.js';
 import * as ComponentHelpers from '../../component_helpers/component_helpers.js';
 import * as Host from '../../host/host.js';
 import * as Platform from '../../platform/platform.js';
@@ -11,13 +10,28 @@
 // eslint-disable-next-line rulesdir/es_modules_import
 import * as UI from '../../ui/ui.js';
 
-const {ls} = Common;
-
 const coordinator = Coordinator.RenderCoordinator.RenderCoordinator.instance();
 
 import {addColumnVisibilityCheckboxes, addSortableColumnItems} from './DataGridContextMenuUtils.js';
 import {calculateColumnWidthPercentageFromWeighting, calculateFirstFocusableCell, Cell, CellPosition, Column, ContextMenuHeaderResetClickEvent, getRowEntryForColumnId, handleArrowKeyNavigation, renderCellValue, Row, SortDirection, SortState} from './DataGridUtils.js';
 
+import * as i18n from '../../i18n/i18n.js';
+export const UIStrings = {
+  /**
+  *@description A context menu item in the Data Grid of a data grid
+  */
+  sortBy: 'Sort By',
+  /**
+  *@description A context menu item in data grids to reset the columns to their default weight
+  */
+  resetColumns: 'Reset Columns',
+  /**
+  *@description A context menu item in data grids to list header options.
+  */
+  headerOptions: 'Header Options',
+};
+const str_ = i18n.i18n.registerUIStrings('ui/components/DataGrid.ts', UIStrings);
+const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
 export interface DataGridContextMenusConfiguration {
   headerRow?: (menu: UI.ContextMenu.ContextMenu, columns: readonly Column[]) => void;
   bodyRow?: (menu: UI.ContextMenu.ContextMenu, columns: readonly Column[], row: Readonly<Row>) => void;
@@ -514,10 +528,10 @@
 
     const menu = new UI.ContextMenu.ContextMenu(event);
     addColumnVisibilityCheckboxes(this, menu);
-    const sortMenu = menu.defaultSection().appendSubMenuItem(ls`Sort By`);
+    const sortMenu = menu.defaultSection().appendSubMenuItem(i18nString(UIStrings.sortBy));
     addSortableColumnItems(this, sortMenu);
 
-    menu.defaultSection().appendItem(ls`Reset Columns`, () => {
+    menu.defaultSection().appendItem(i18nString(UIStrings.resetColumns), () => {
       this.dispatchEvent(new ContextMenuHeaderResetClickEvent());
     });
 
@@ -551,12 +565,12 @@
     const rowThatWasClicked = this.rows[rowIndex - 1];
 
     const menu = new UI.ContextMenu.ContextMenu(event);
-    const sortMenu = menu.defaultSection().appendSubMenuItem(ls`Sort By`);
+    const sortMenu = menu.defaultSection().appendSubMenuItem(i18nString(UIStrings.sortBy));
     addSortableColumnItems(this, sortMenu);
 
-    const headerOptionsMenu = menu.defaultSection().appendSubMenuItem(ls`Header Options`);
+    const headerOptionsMenu = menu.defaultSection().appendSubMenuItem(i18nString(UIStrings.headerOptions));
     addColumnVisibilityCheckboxes(this, headerOptionsMenu);
-    headerOptionsMenu.defaultSection().appendItem(ls`Reset Columns`, () => {
+    headerOptionsMenu.defaultSection().appendItem(i18nString(UIStrings.resetColumns), () => {
       this.dispatchEvent(new ContextMenuHeaderResetClickEvent());
     });
 
diff --git a/front_end/ui/components/SurveyLink.ts b/front_end/ui/components/SurveyLink.ts
index 473e933..ae2debe 100644
--- a/front_end/ui/components/SurveyLink.ts
+++ b/front_end/ui/components/SurveyLink.ts
@@ -8,7 +8,23 @@
 
 import type {IconData} from './Icon.js';
 
-const ls = Common.ls;
+import * as i18n from '../../i18n/i18n.js';
+export const UIStrings = {
+  /**
+  *@description Text shown when the link to open a survey is clicked but the survey has not yet appeared
+  */
+  openingSurvey: 'Opening survey …',
+  /**
+  *@description Text displayed instead of the survey link after the survey link is clicked, if the survey was shown successfully
+  */
+  thankYouForYourFeedback: 'Thank you for your feedback',
+  /**
+  *@description Text displayed instead of the survey link after the survey link is clicked, if the survey was not shown successfully
+  */
+  anErrorOccurredWithTheSurvey: 'An error occurred with the survey',
+};
+const str_ = i18n.i18n.registerUIStrings('ui/components/SurveyLink.ts', UIStrings);
+const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
 
 export type CanShowSurveyCallback = (result: Host.InspectorFrontendHostAPI.CanShowSurveyResult) => void;
 export type ShowSurveyCallback = (result: Host.InspectorFrontendHostAPI.ShowSurveyResult) => void;
@@ -81,11 +97,11 @@
 
     let linkText = this.promptText;
     if (this.state === State.Sending) {
-      linkText = ls`Opening survey …`;
+      linkText = i18nString(UIStrings.openingSurvey);
     } else if (this.state === State.SurveyShown) {
-      linkText = ls`Thank you for your feedback`;
+      linkText = i18nString(UIStrings.thankYouForYourFeedback);
     } else if (this.state === State.Failed) {
-      linkText = ls`An error occurred with the survey`;
+      linkText = i18nString(UIStrings.anErrorOccurredWithTheSurvey);
     }
 
     let linkState = '';
diff --git a/front_end/ui/components/components_strings.grdp b/front_end/ui/components/components_strings.grdp
deleted file mode 100644
index b4933ac..0000000
--- a/front_end/ui/components/components_strings.grdp
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<grit-part>
-  <message name="IDS_DEVTOOLS_059a1aa256b770eca2d69c096f759ad0" desc="A context menu item in the Data Grid of a data grid">
-    Sort By
-  </message>
-  <message name="IDS_DEVTOOLS_17022809d53876ba5d6b97c67c364614" desc="A context menu item in data grids to list header options.">
-    Header Options
-  </message>
-  <message name="IDS_DEVTOOLS_2d1a0357b8c9e3ec6634b8dad39764c5" desc="A context menu item in data grids to reset the columns to their default weight">
-    Reset Columns
-  </message>
-  <message name="IDS_DEVTOOLS_7f7208f102493356f51e7eb55dd157a1" desc="Text displayed instead of the survey link after the survey link is clicked, if the survey was shown successfully">
-    Thank you for your feedback
-  </message>
-  <message name="IDS_DEVTOOLS_d47d1a9538df32f314e56fd640ddc754" desc="Text displayed instead of the survey link after the survey link is clicked, if the survey was not shown successfully">
-    An error occurred with the survey
-  </message>
-  <message name="IDS_DEVTOOLS_fb5f2364eb32a3ea2051c7a7792569a3" desc="Text shown when the link to open a survey is clicked but the survey has not yet appeared">
-    Opening survey …
-  </message>
-</grit-part>
\ No newline at end of file
diff --git a/front_end/ui/ui_strings.grdp b/front_end/ui/ui_strings.grdp
deleted file mode 100644
index 7b7dec8..0000000
--- a/front_end/ui/ui_strings.grdp
+++ /dev/null
@@ -1,222 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<grit-part>
-  <message name="IDS_DEVTOOLS_0118d8300f0ad71843ef9f47acca779f" desc="Text on a menu option to close other drawers when right click on a drawer title">
-    Close others
-  </message>
-  <message name="IDS_DEVTOOLS_0cbca9a34ab68b4be10dd4d09dd61bfd" desc="Text on a button to search previous instance for the ctrl+F search bar">
-    Search previous
-  </message>
-  <message name="IDS_DEVTOOLS_0ebe6df8a3ac338e0512acc741823fdb" desc="Text on a button to replace one instance with input text for the ctrl+F search bar">
-    Replace
-  </message>
-  <message name="IDS_DEVTOOLS_103e6e056329361a5d169154f52771d0" desc="Text in UIUtils">
-    <ph name="DESCRIPTION">$1s<ex>Promise</ex></ph> (async)
-  </message>
-  <message name="IDS_DEVTOOLS_1063e38cb53d94d386f21227fcd84717" desc="Label for an item to remove something">
-    Remove
-  </message>
-  <message name="IDS_DEVTOOLS_1886cc68b0d9c0a0f4a9436258cf11e1" desc="Days format in UIUtils">
-    <ph name="PH1">$1.1f<ex>2.2</ex></ph> days
-  </message>
-  <message name="IDS_DEVTOOLS_1aff765143dc4bf8ef68f698234e10f6" desc="Name of the category that hold recording related actions">
-    Recorder
-  </message>
-  <message name="IDS_DEVTOOLS_1b1ac1c7a54457ce73ddd25a5b51c47d" desc="A title of the 'Drawer sidebar' @UI.ViewLocationResolver category">
-    Drawer sidebar
-  </message>
-  <message name="IDS_DEVTOOLS_214864980ac9b83ff82c6e9b8c9a44c7" desc="Aria alert to read the suggestion for the suggestion box when typing in text editor">
-    <ph name="THIS__ONLYCOMPLETION_TEXT">$1s<ex>name</ex></ph>, suggestion <ph name="THIS__LIST_SELECTEDINDEX______">$2s<ex>2</ex></ph> of <ph name="THIS__ITEMS_LENGTH">$3s<ex>5</ex></ph>
-  </message>
-  <message name="IDS_DEVTOOLS_2ce2fc341b0bd9219a3634ff43a90bde" desc="Generic text with two placeholders separated by a comma">
-    <ph name="ITEM_LABEL">$1s<ex>1 613 680</ex></ph>, <ph name="CHECKEDSTATE">$2s<ex>44 %</ex></ph>
-  </message>
-  <message name="IDS_DEVTOOLS_2d56db467b153fe19f6f059f7f29be97" desc="Hours format in UIUtils">
-    <ph name="PH1">$1.1f<ex>2.2</ex></ph> hrs
-  </message>
-  <message name="IDS_DEVTOOLS_2ea54663ae9e3a586132a34a98d85ccf" desc="Text for the title of asynchronous function calls group in Call Stack">
-    Async Call
-  </message>
-  <message name="IDS_DEVTOOLS_2f04f3e6eee339eeb0ddb6c39606424d" desc="Text for searching with regular expressinn">
-    Use Regular Expression
-  </message>
-  <message name="IDS_DEVTOOLS_3793ea52a7be2d7deafd858fda50775c" desc="Text exposed to screen readers on checked items.">
-    checked
-  </message>
-  <message name="IDS_DEVTOOLS_3a39eb38e879f66d1c57dedd478272da" desc="label to open link externally">
-    Open in new tab
-  </message>
-  <message name="IDS_DEVTOOLS_3afbd9828e011526955ca93b48b57524" desc="Text for one or a group of screenshots">
-    Screenshot
-  </message>
-  <message name="IDS_DEVTOOLS_3b41735478b3a3fd8bcc06f6c7a6b56c" desc="label to copy link address">
-    Copy link address
-  </message>
-  <message name="IDS_DEVTOOLS_4cfa6c981549e990fe2344e4c805405e" desc="Text to find an item">
-    Find
-  </message>
-  <message name="IDS_DEVTOOLS_727b701bcc5f26422461f10c07a58d48" desc="Text for context menu action to move a tab to the main panel">
-    Move to top
-  </message>
-  <message name="IDS_DEVTOOLS_3dc4bfdcf1b17a60979e2872cdd0922a" desc="Text on a button to close the infobar and never show the infobar in the future">
-    Don&apos;t show again
-  </message>
-  <message name="IDS_DEVTOOLS_44ac014b674d7d86a04702e6fd1fa858" desc="Text in a dialog box showing how to reconnect to DevTools when remote debugging has been terminated">
-    Reconnect when ready by reopening <ph name="LOCKED_1">DevTools</ph>.
-  </message>
-  <message name="IDS_DEVTOOLS_45b471827af8ba9628e1914afbb13980" desc="Minutes format in UIUtils">
-    <ph name="PH1">$1.1f<ex>2.2</ex></ph> min
-  </message>
-  <message name="IDS_DEVTOOLS_47e0270ab1827aab8faa1c85d89bd48f" desc="Text that appears when hover over the All button in the Network tool">
-    <ph name="UI_KEYBOARDSHORTCUT_SHORTCUTTOSTRING_____UI_KEYBOARDSHORTCUT_MODIFIERS_CTRLORMETA_">$1s<ex>Ctrl + </ex></ph>Click to select multiple types
-  </message>
-  <message name="IDS_DEVTOOLS_48f12760504bf8e958a4bdde56d4fa46" desc="Text to indicate search result for the ctrl+F search bar">
-    1 match
-  </message>
-  <message name="IDS_DEVTOOLS_56797cefb1efc9130f7c48a7d1db0f0c" desc="The aria label for main tabbed pane that contains Panels">
-    Panels
-  </message>
-  <message name="IDS_DEVTOOLS_5ccb2f9327ce0aba7567b62e9e1d15a5" desc="Text on a menu option to close the drawer to the right when right click on a drawer title">
-    Close tabs to the right
-  </message>
-  <message name="IDS_DEVTOOLS_63e29f78b2e7788d9234a5790897fa71" desc="Text in dialog box when the target page crashed">
-    <ph name="LOCKED_1">DevTools</ph> was disconnected from the page.
-  </message>
-  <message name="IDS_DEVTOOLS_70e8cfcb06bc768ce53af9757940cb67" desc="Micros format in UIUtils">
-    <ph name="PH1">$1.0f<ex>2</ex></ph> μs
-  </message>
-  <message name="IDS_DEVTOOLS_7102e4c0bf381bdbaa934e3dccb5b283" desc="Text for the name of anonymous functions">
-    (anonymous)
-  </message>
-  <message name="IDS_DEVTOOLS_7423ba80f2fff2568d2c642c6be84ede" desc="Text that appears when hovor over the close button on the drawer view">
-    Close drawer
-  </message>
-  <message name="IDS_DEVTOOLS_7cf206a681131cf4d86fc190f2d9ad27" desc="Text on a button to reconnect Devtools when remote debugging terminated">
-    Reconnect <ph name="LOCKED_1">DevTools</ph>
-  </message>
-  <message name="IDS_DEVTOOLS_7dce122004969d56ae2e0245cb754d35" desc="Text on a button to start editing text">
-    Edit
-  </message>
-  <message name="IDS_DEVTOOLS_7e97bc09f074ed05b7afd49cb4ba0411" desc="Millis format in UIUtils">
-    <ph name="PH1">$1.0f<ex>2</ex></ph> ms
-  </message>
-  <message name="IDS_DEVTOOLS_805cc3d38ed574dd03e4483501c0d34e" desc="Note when a setting change will require the user to reload DevTools">
-    <ph name="___">$1s<ex>*</ex></ph>Requires reload
-  </message>
-  <message name="IDS_DEVTOOLS_846495f9ceed11accf8879f555936a7d" desc="A title of the 'Navigation' action category">
-    Navigation
-  </message>
-  <message name="IDS_DEVTOOLS_84e1d403df34bad00840ee636021698c" desc="Text in Tabbed Pane">
-    Close <ph name="THIS_TITLE">$1s<ex>tab</ex></ph>
-  </message>
-  <message name="IDS_DEVTOOLS_86e8f8f8327d28b74e5bd3ab581f77ee" desc="Text that appears when hover over the filter bar in the Network tool">
-    e.g. <ph name="LOCKED_1">/small[\d]+/ url:a.com/b</ph>
-  </message>
-  <message name="IDS_DEVTOOLS_87bfda183c4f851a101e97bbb1bbace7" desc="Title of the Layers tool">
-    Layers
-  </message>
-  <message name="IDS_DEVTOOLS_894dab8359b886762113f6b64ce9f107" desc="Text on a button to replace all instances with input text for the ctrl+F search bar">
-    Replace all
-  </message>
-  <message name="IDS_DEVTOOLS_8ca37a9854bdfeea9616a8f52ff6f9de" desc="Aria label for the tab panel view container">
-    <ph name="VIEW_TITLE__">$1s<ex>Sensors</ex></ph> panel
-  </message>
-  <message name="IDS_DEVTOOLS_8e44b2127a4fb456a78feced6731a496" desc="Text to indicate the current match index and the total number of matches for the ctrl+F search bar">
-    <ph name="CURRENTMATCHINDEX____">$1d<ex>2</ex></ph> of <ph name="MATCHES">$2d<ex>3</ex></ph>
-  </message>
-  <message name="IDS_DEVTOOLS_925f3a6eef3896d617fc0ab413f9c123" desc="Text to indicate search result for the ctrl+F search bar">
-    <ph name="MATCHES">$1d<ex>2</ex></ph> matches
-  </message>
-  <message name="IDS_DEVTOOLS_96fb9e0d650af5b1fc4ec6c7bc11b49b" desc="Title of more tabs button in inspector view">
-    More Tools
-  </message>
-  <message name="IDS_DEVTOOLS_9b1ed2cbe56f7a315f0a365d2b97cb59" desc="A title of the 'Drawer' @UI.ViewLocationResolver category">
-    Drawer
-  </message>
-  <message name="IDS_DEVTOOLS_a169aab715858133b50d2e72ece74f14" desc="Accessibility label for checkable SoftContextMenuItems with shortcuts">
-    <ph name="ITEM_LABEL">$1s<ex>Open File</ex></ph>, <ph name="ITEM_SHORTCUT">$2s<ex>Ctrl + P</ex></ph>, <ph name="CHECKEDSTATE">$3s<ex>checked</ex></ph>
-  </message>
-  <message name="IDS_DEVTOOLS_a950da8e902568f9a6879abe4313efe7" desc="Text content of content element">
-    Once page is reloaded, <ph name="LOCKED_1">DevTools</ph> will automatically reconnect.
-  </message>
-  <message name="IDS_DEVTOOLS_ad91a1da588ce256d30b1af38f78f84e" desc="Text exposed to screen readers on unchecked items.">
-    unchecked
-  </message>
-  <message name="IDS_DEVTOOLS_adf7e09e4a939c3d54adfe6f42b6ead9" desc="label to copy file name">
-    Copy file name
-  </message>
-  <message name="IDS_DEVTOOLS_b1c94ca2fbc3e78fc30069c8d0f01680" desc="Text for everything">
-    All
-  </message>
-  <message name="IDS_DEVTOOLS_b6da8d6392710f305d7176a134971514" desc="Text in UIUtils">
-    Promise rejected (async)
-  </message>
-  <message name="IDS_DEVTOOLS_b8da6df14bf06283cbf588df6998722e" desc="A title of the 'Panel' @UI.ViewLocationResolver category">
-    Panel
-  </message>
-  <message name="IDS_DEVTOOLS_b94d1b250ba62f06dadf0edc4a947f5c" desc="Text in UIUtils">
-    Promise resolved (async)
-  </message>
-  <message name="IDS_DEVTOOLS_c1ea3facd2946b59df718d8dd2737cfa" desc="Text in Application Panel Sidebar of the Application panel">
-    Background Services
-  </message>
-  <message name="IDS_DEVTOOLS_c486d3222f16146af0711d84a14b62fb" desc="Sub millis format in UIUtils">
-    <ph name="PH1">$1.2f<ex>2.14</ex></ph> ms
-  </message>
-  <message name="IDS_DEVTOOLS_c949475bc69a57c419ac976fe8870652" desc="Text to search by matching case of the input">
-    Match Case
-  </message>
-  <message name="IDS_DEVTOOLS_c9cc8cce247e49bae79f15173ce97354" desc="Text to save something">
-    Save
-  </message>
-  <message name="IDS_DEVTOOLS_d06337cfbcc777e0a7caa50ef1a9986a" desc="The aria label for the button to open more tabs at the right tabbed pane in Elements tools">
-    More tabs
-  </message>
-  <message name="IDS_DEVTOOLS_d3d2e617335f08df83599665eef8a418" desc="Text to close something">
-    Close
-  </message>
-  <message name="IDS_DEVTOOLS_d59048f21fd887ad520398ce677be586" desc="Text that is usually a hyperlink to more documentation">
-    Learn more
-  </message>
-  <message name="IDS_DEVTOOLS_d7778d0c64b6ba21494c97f77a66885a" desc="Text to filter result items">
-    Filter
-  </message>
-  <message name="IDS_DEVTOOLS_d916eea6390ddc39ee5fbc5c984e940c" desc="Seconds format in UIUtils">
-    <ph name="PH1">$1.2f<ex>2.14</ex></ph> s
-  </message>
-  <message name="IDS_DEVTOOLS_ddcf50c29294d4414f3f7c1bbc892cb5" desc="A title of the 'Resources' action category">
-    Resources
-  </message>
-  <message name="IDS_DEVTOOLS_dde38f333e095c2293593f504fd701a2" desc="Title of the 'JavaScript Profiler' tool">
-    JavaScript Profiler
-  </message>
-  <message name="IDS_DEVTOOLS_e0aa021e21dddbd6d8cecec71e9cf564" desc="Text on a button for message dialog">
-    OK
-  </message>
-  <message name="IDS_DEVTOOLS_e6290b661dba9591e4c505fb50257d0c" desc="Text on a button to search next instance for the ctrl+F search bar">
-    Search next
-  </message>
-  <message name="IDS_DEVTOOLS_e9947a82726be2fb77368eb27c082402" desc="Placeholder text in Soft Drop Down">
-    (no item selected)
-  </message>
-  <message name="IDS_DEVTOOLS_ad2ac1967f0165ebf04a84bc1819e0de" desc="Text for context menu action to move a tab to the drawer">
-    Move to bottom
-  </message>
-  <message name="IDS_DEVTOOLS_ea4788705e6873b424c65e91c2846b19" desc="Text to cancel something">
-    Cancel
-  </message>
-  <message name="IDS_DEVTOOLS_ec211f7c20af43e742bf2570c3cb84f9" desc="Text to add something">
-    Add
-  </message>
-  <message name="IDS_DEVTOOLS_ee611c8b9dfbbc792a9318c9837b2bcd" desc="A title of the 'Inputs' action category">
-    Inputs
-  </message>
-  <message name="IDS_DEVTOOLS_f4f70727dc34561dfde1a3c529b6205c" desc="A title of the 'Settings' @UI.ViewLocationResolver category">
-    Settings
-  </message>
-  <message name="IDS_DEVTOOLS_f8fbc6412a360fc4f854f34a776e2af2" desc="label for the profiler control button">
-    Another profiler is already active
-  </message>
-  <message name="IDS_DEVTOOLS_fbbbb283efc814825613301c22951ba7" desc="Text on a menu option to close all the drawers except Console when right click on a drawer title">
-    Close all
-  </message>
-</grit-part>