Migrating from Polylang
PerfLocale’s Polylang importer reads the post_translations and term_translations taxonomies and rebuilds your translation groups as native PerfLocale rows. Polylang’s data is read-only during the import - nothing is touched in its tables.
If you haven’t already, start with the migration overview for the shared pre-flight steps (backup, install PerfLocale, add languages).
What’s imported
- Post translations - Polylang stores translation groups as serialised PHP arrays in the
descriptionfield of eachpost_translationsterm. The importer unserialises those, looks up each post by ID, and rebuilds the group in PerfLocale. - Term translations - same approach with the
term_translationstaxonomy: categories, tags, and any custom taxonomies Polylang was tracking.
What’s not imported
- String translations. The Polylang importer only handles posts and terms. If you use Polylang String Translations (the companion plugin or pro addon) for theme/plugin UI strings, those aren’t carried over. After the migration, scan the site with
wp perflocale strings scanto rebuild the string catalogue, then translate the strings again in the PerfLocale admin. For most sites this is a handful of strings, but budget time for it. - Menus & widgets. Polylang uses a different mechanism for menu / widget language-scoping (per-location menu variants). PerfLocale’s menu model is translation-group based, so menus need to be rebuilt post-import.
- Language-switcher widget configuration. Polylang’s widget settings don’t carry across - configure PerfLocale’s Language Switcher block, widget, or shortcode from scratch.
- Custom language flags and display names. Re-add them in PerfLocale → Languages when you create the matching PerfLocale language.
Pre-flight checks
Polylang doesn’t have to be active
The importer works both with Polylang active and with Polylang deactivated. Detection is two-layered:
- If the
languagetaxonomy is registered (Polylang is active), the importer uses it. - If Polylang is deactivated but its data remains in the database (
languageterms inwp_term_taxonomy), the importer detects that and proceeds anyway.
Practically: if you already switched off Polylang, the migration still works. You can activate it again to ease verification, or leave it off - either is fine.
Match your language codes
The importer maps Polylang’s language slug (e.g. fr, de) to a PerfLocale language using:
- Exact slug match first.
- Locale-prefix fallback: PerfLocale’s
localestarts-with Polylang’s slug (e.g. PerfLocalefr_FRmatches Polylangfr).
If your Polylang install used full locale slugs like en_gb, add a PerfLocale language with the matching slug exactly. Unmatched languages are reported as warnings (“No PerfLocale language match for Polylang slug
Run the import
From the admin
- Go to PerfLocale → Settings → Export & Import.
- Scroll to “Import from Polylang”. If the button isn’t shown, Polylang data wasn’t detected - the
languagetaxonomy doesn’t exist and there are nolanguageterms in the DB. - Click Import from Polylang. Confirm the prompt.
- On completion the page reloads with a count of posts and terms imported.
From WP-CLI
# Confirm Polylang data is detected.
wp perflocale migrate polylang --dry-run
# Run the real import (prompts for confirmation).
wp perflocale migrate polylang
# Skip the prompt when scripting.
wp perflocale migrate polylang --yes
Verification
- Post counts match. Compare the post-translation counts reported by the importer against your expected counts (Polylang’s admin → Languages tab shows totals per language).
- Spot-check a post. Open any multilingual post. The PerfLocale sidebar should list every language that had a translation in Polylang.
- Check terms. Confirm translated categories / tags are linked in the PerfLocale translation column.
- Visit translated URLs. Polylang’s URL prefix convention (e.g.
/fr/) is matched by PerfLocale’s defaultslug-based prefix, so existing URLs should continue resolving. Browse a handful and confirm they render the right language. - Rebuild strings. If you used Polylang String Translations, run
wp perflocale strings scan --target=themeand--target=plugins, then work through PerfLocale → Strings to re-translate them.
Re-running the import
The importer is idempotent. For each Polylang translation term, it looks for an existing PerfLocale group that already contains any of the posts listed - if found, it reuses the group and adds missing siblings. Already-linked siblings at the same language/group are skipped. If your first run warned about a language you hadn’t added yet, add it and re-run; the new language’s content fills in without duplicating the rest.
Rollback
No automatic rollback. The safe paths:
- Restore from backup - the cleanest undo.
- Reactivate Polylang - Polylang’s data is untouched, so reactivating restores its behaviour. PerfLocale’s newly-created translation groups will sit alongside Polylang’s without interfering (PerfLocale only acts when its own data is present and the plugin is active).
Troubleshooting
“Polylang language taxonomy not found”
Either Polylang was never set up on this site, or its data was deleted. Check for language rows in wp_term_taxonomy: SELECT COUNT(*) FROM wp_term_taxonomy WHERE taxonomy = 'language';. If the count is zero, there’s nothing to migrate.
The import timed out
Switch to WP-CLI. Admin-UI requests are bounded by PHP’s request timeout; WP-CLI isn’t.
My translated strings didn’t come across
Expected - the Polylang importer doesn’t handle strings. See “What’s not imported” above.
Next steps
- Run the string scanner to rebuild the catalogue: see WP-CLI: scan for strings.
- Configure language fallbacks.
- See the PerfLocale vs Polylang feature comparison for what’s available in PerfLocale that Polylang charges Pro for.