Select Game Version

SDEditor is a translation editor for Path of Exile StatDescriptions files, with optional Google backup for settings and shared language dictionaries.

Choose the Path of Exile version you are translating. Source files, workspace data, and history are stored separately for each version.

Privacy policy

Move Existing Data?

We found SDEditor data from before PoE1/PoE2 split storage. It looks like {{ formatGameVersion(pendingSingleVersionMigration.detectedVersion) }} data.

This copies your old source, workspace, and revision history into the new {{ formatGameVersion(pendingSingleVersionMigration.detectedVersion) }} storage. The old data is left untouched as a backup.

Source files: {{ pendingSingleVersionMigration.sourceCount }}
Workspace files: {{ pendingSingleVersionMigration.workspaceCount }}
History entries: {{ pendingSingleVersionMigration.revisionCount }}

Copying your old data into the new {{ formatGameVersion(pendingSingleVersionMigration.detectedVersion) }} storage…

⚠️ Multiple Instances Detected

You have more than one instance of SDEditor open in your browser. This can cause data loss or conflicts if you save translations simultaneously across multiple tabs or windows.

Warning: Each instance maintains its own in-memory state and may have outdated translations from IndexedDB. Concurrent edits can cause data loss.

What should I do?

  • Use only one instance at a time and close other tabs/windows before editing
  • Save frequently and reload before switching instances
  • Consider exporting translations between instances to avoid conflicts

You can close this message, but please be careful about data loss.

Resolve Duplicate Language Entries

{{ duplicateLangImportWarning.fileName }} contains duplicated lang blocks. Choose the entry SDEditor should keep for each duplicate group, then confirm to continue importing.

Review every language listed, even if it is not your selected translation language. SDEditor will keep the selected entries for this import and ignore the other duplicated blocks.

Duplicate groups ({{ duplicateLangImportWarning.groups.length }})

{{ group.lang }} {{ group.filepath }}

Select one entry for each duplicate group to enable Confirm. Remaining: {{ duplicateLangResolutionRemainingCount() }}.

Welcome to SDEditor!

Read the Editor guide for more information.

Privacy policy

* It is recommended to import the last version of StatDescriptions.zip first.

Initializing...

Please wait while we initialize the workspace. This can take a moment.

Loading: {{ loadingProgress.toFixed(2) }}%

SDEditor{{ gameVersionLabel }} {{ lang }}
{{ filterShortcutCtrlD ? 'Ctrl D' : 'Ctrl F' }}

Import

This is what you normally do when you get a new export.
This is rarely used; it is for when you want to move translated data between PCs.
Click outside to cancel.

Arrow Up and Down return to the current selection or move between files while the list is focused. Arrow Down from search selects the first file. Home and End select the first and last files on the current page. Page Up and Page Down move ten files. Arrow Left and Right change page; the next page selects its first file and the previous page selects its last file. Click a row or press Enter to open it.

Stat descriptions in {{ lang }}. Open a filename to edit its translations.
{{ (desc.hasDiagnosticError ? '[ERROR] ' : (desc.hasDiagnosticWarning ? '[WARNING] ' : '')) + elipsisRenderer(desc.filedir) }} Needs review

{{ selectedFileFilters.length ? 'No files match your search' : 'Choose a status to show files' }}

{{ selectedFileFilters.length ? 'Try another search or open Filters to select more statuses.' : 'Open Filters and tick one or more statuses to see matching stat files.' }}

{{ descs.length }} loaded files Missing {{ statistic.isMissing }} Saved {{ statistic.hasChanges }} Review {{ statistic.needsReview }}
Preview size
EN
(empty)
{{ translationEditorBcp47 || lang || 'TL' }}
(empty)
{}
No variables

🧾 Translation

Warning: {{ editorDiagnosticWarningCount }} Error: {{ editorDiagnosticErrorCount }}

📁 Filepath: {{ editorCurrentEditingDesc.filepath }}

{{ consistencyResolutionNotice }}
{{ editorCompareTitle }}
⚠ Source changed since your last translation save.
{{ column.englishHLter }}
{{ column.translationHLter }}
@
↵
{{ editorBlock.translationHLter }}
{{ editorBlock.translationHLter }}
↵{{ editorBlock.metaLinesTr }}/{{ editorBlock.metaLinesEn }} @{{ editorBlock.metaColsTr }}/{{ editorBlock.metaColsEn }} {}{{ editorBlock.metaVarsTr }}/{{ editorBlock.metaVarsEn }} []{{ editorBlock.metaKwTr }}/{{ editorBlock.metaKwEn }} <>{{ editorBlock.metaDecorTr }}/{{ editorBlock.metaDecorEn }} !{{ blockDiagnosticWarningCount(editorBlock, index) }} x{{ editorBlock.diagnosticErrorCount }}
Inconsistent translations{{ editorConsistencyDiagnostics[index].variantCount }} versions across {{ editorConsistencyDiagnostics[index].entryCount }} entries with identical English
{{ Number.isInteger(diagnostic.columnIndex) ? ('Column ' + (diagnostic.columnIndex + 1) + ': ') : '' }}{{ diagnostic.message }}
Alternates
TL note
Open a file to see history
{{ editorCurrentEditingDesc.filename }}
{{ historyMode === 'source' ? 'English' : lang }}
Loading…
No revisions yet
Click a revision to compare against current Comparing current → {{ formatHistoryTime(historySelectedB.savedAt) }}
{{ item.label }} {{ hlPopupCtrlEnterPillText(item) }}
No highlights

Scan diagnostics

Check every loaded {{ lang }} file, including files hidden by filters.

{{ diagnosticScanErrorFileCount }} {{ diagnosticScanErrorFileCount === 1 ? 'file' : 'files' }} with errors · {{ diagnosticScanIssueCounts.errors }} {{ diagnosticScanIssueCounts.errors === 1 ? 'issue' : 'issues' }} {{ diagnosticScanWarningFileCount }} {{ diagnosticScanWarningFileCount === 1 ? 'file' : 'files' }} with warnings · {{ diagnosticScanIssueCounts.warnings }} {{ diagnosticScanIssueCounts.warnings === 1 ? 'issue' : 'issues' }} {{ diagnosticScanTotal - diagnosticScanResultFiles.length }} {{ diagnosticScanTotal - diagnosticScanResultFiles.length === 1 ? 'file' : 'files' }} without findings

You can close this window while the scan runs and reopen it from Scan diagnostics.

{{ diagnosticScanResultFiles.length ? 'Files to review' : 'No issues found' }}

{{ diagnosticScanResultFiles.length }} {{ diagnosticScanResultFiles.length === 1 ? 'file' : 'files' }}

The selected checks found no errors or warnings.

{{ entry.filepath }}

{{ entry.result.errorCount }} {{ entry.result.errorCount === 1 ? 'error' : 'errors' }} {{ entry.result.warningCount }} {{ entry.result.warningCount === 1 ? 'warning' : 'warnings' }}
  • {{ diagnosticScanIssueLocation(issue) }} · {{ issue.level }} {{ issue.message || issue.code }}
{{ entry.result.diagnostics.length - 3 }} more {{ entry.result.diagnostics.length - 3 === 1 ? 'issue' : 'issues' }}
  • {{ diagnosticScanIssueLocation(issue) }} · {{ issue.level }} {{ issue.message || issue.code }}

{{ entry.result.diagnosticsTruncated }} more {{ entry.result.diagnosticsTruncated === 1 ? 'finding' : 'findings' }}. Open the file to review all entries.

Diagnostic checks {{ diagnosticScanTypes.filter(type => diagnosticScanChecks[type.key]).length }} selected
Diagnostic types

Dictionary terminology and inconsistent translations are checked only by a manual scan.

Esc to close