Миграция с Joomla на WordPress: план переезда без потери позиций
Как перенести материалы, категории и адреса со старой Joomla, что делать с расширениями и как сохранить трафик после смены движка.
Содержание
- Когда переезд оправдан, а когда дешевле остаться
- Инвентаризация: без неё переезд превращается в лотерею
- Перенос контента: импортер против ручного экспорта
- Картинки и вложения: где они лежат в Joomla
- Карта редиректов: главный пункт всей затеи
- Чем заменить расширения Joomla
- Сколько это стоит и сколько занимает
- Приёмка: чек-лист на две недели после переезда
- Что делать прямо сейчас
- Частые вопросы
Главный пункт переезда с Joomla это карта редиректов со старых адресов на новые. Без неё через две недели посещаемость падает на десятки процентов. Перенос среднего сайта с версткой шаблона под свой дизайн обходится в 150-300 тысяч рублей.
Миграция с Joomla на WordPress почти всегда начинается одинаково: подрядчик, который делал сайт в 2015 году, пропал, обновить движок некому, а последний человек, знавший пароль от админки, уволился. Статья для владельцев корпоративных сайтов и каталогов на Joomla 3.x, которым надоело жить на замороженной CMS. Разберём, что переносится автоматически, что придётся руками, где переезд ломает трафик и как этого не допустить. Главное в этой истории не контент, а карта редиректов: контент перетащит любой импортер, а позиции теряются на адресах.

Я вёл несколько таких переездов, самый крупный на 1 400 материалов и 60 разделов. Ниже порядок работ, который у меня устоялся, с оговорками про то, где обычно больно.
Когда переезд оправдан, а когда дешевле остаться
Смена CMS это не косметика, это две-четыре недели работы и риск просадки трафика на месяц. Причина должна быть весомее, чем «WordPress сейчас популярнее».
Переезд оправдан, если совпало хотя бы два пункта:
- сайт на Joomla 3.x, поддержка которой закончилась в августе 2023 года, и обновление до 5.x упирается в шаблон или платные расширения, которых больше не существует;
- нужны регулярные правки контента силами сотрудника, а не подрядчика, и человек саботирует редактор Joomla;
- сайт живёт на PHP 7.4, хостинг требует перейти на 8.2, а старые расширения на 8.2 падают в фатальные ошибки;
- нет ни одного разработчика в радиусе досягаемости, который согласится трогать этот код за адекватные деньги.
Оставаться на Joomla разумно, когда сайт уже на 5.x, шаблон живой, расширения обновляются, а раздражает только непривычная админка. Тогда дешевле навести порядок на месте: почистить неиспользуемые расширения, обновить PHP, поставить нормальные бэкапы. Подробнее о том, в каком состоянии движок находится сегодня и стоит ли его хоронить, я писал в отдельном разборе про Joomla.
Отдельно про деньги. Сайт с нуля на WordPress со сборкой шаблона под ваш дизайн обойдётся порядка 150 000-300 000 рублей. Аккуратная миграция контента на готовую тему с сохранением структуры стоит 30 000-80 000 в зависимости от объёма. Если контент ценный и позиции есть, миграция почти всегда выгоднее, чем начинать заново.
Инвентаризация: без неё переезд превращается в лотерею
Первое, что делаю, до установки WordPress: описываю, что вообще есть на старом сайте. Не по памяти владельца, а по базе и файловой системе.
Что считаю обязательным зафиксировать:
| Объект | Где смотреть в Joomla | Куда поедет в WordPress |
|---|---|---|
| Материалы | таблица #__content | записи или страницы |
| Категории | #__categories | рубрики или иерархия страниц |
| Меню и структура | #__menu | меню WordPress, вручную |
| Пользователи | #__users | пользователи, пароли не переносятся |
| Картинки | /images/ | /wp-content/uploads/ |
| Формы | RSForm, Convert Forms, BreezingForms | своя форма или Contact Form 7 |
| Модули в позициях | #__modules | виджеты, блоки, части шаблона |
| Расширения | #__extensions | плагины-аналоги или отказ |
Префикс таблиц у Joomla случайный, в старых установках часто jos_, в новых что-то вроде x7k2p_. Смотрится в configuration.php в корне сайта, строка public $dbprefix.
Дальше считаю объёмы. Простой запрос по опубликованным материалам сразу показывает масштаб работ и заодно вылавливает мусор: черновики десятилетней давности, дубли, тестовые статьи с названием «asdf».
SELECT c.state, COUNT(*) AS cnt
FROM jos_content c
GROUP BY c.state;
SELECT cat.title AS category, COUNT(c.id) AS articles
FROM jos_categories cat
LEFT JOIN jos_content c ON c.catid = cat.id AND c.state = 1
GROUP BY cat.id
ORDER BY articles DESC;
Состояния в state: 1 опубликовано, 0 снято с публикации, 2 в архиве, -2 в корзине. Переносить нужно единицы, всё остальное обсуждается с владельцем отдельно. На одном проекте из 2 100 записей в базе живыми оказались 380, остальное копилось годами. Перенос всего подряд обошёлся бы клиенту в лишние 40 тысяч и в помойку на новом сайте.
Отдельным пунктом выписываю кастомный код: правки в ядре Joomla, самописные модули, вставки в шаблон, сторонние скрипты в <head>. Метрика, чат, пиксели рекламных кабинетов, коды подтверждения прав в Вебмастере. Всё это переехать само не может, а отсутствие счётчика на новом сайте обнаруживается через неделю, когда аналитика уже провалена.
Перенос контента: импортер против ручного экспорта
Есть два рабочих пути. Третий, «скопировать текст статей руками», допустим до 30 материалов, дальше это дороже автоматизации.
Готовый импортер
Стандарт индустрии это плагин FG Joomla to WordPress. Бесплатная версия тянет категории, материалы, картинки из тела статей, даты, алиасы. Премиум-аддон (порядка 60-90 евро) добавляет K2, VirtueMart, кастомные поля, меню и пользователей.
Работает он не с файлом экспорта, а напрямую с базой Joomla. Значит, старая база должна быть доступна: либо оба сайта на одном хостинге, либо у пользователя MySQL разрешён внешний доступ по IP. На Timeweb и подобных внешний доступ включается в панели, на некоторых хостингах не включается вообще, тогда базу Joomla разворачивают локально или рядом с новым сайтом временной копией.
Что спросит плагин: хост, имя базы, пользователь, пароль, префикс таблиц, URL старого сайта. Дальше галочки: переносить ли снятые с публикации, скачивать ли медиа, ставить ли редиректы алиасов.
Что импортер делает плохо, проверял многократно:
- разделы Joomla с глубокой вложенностью схлопывает в плоские рубрики;
- теряет разрыв
{readmore}междуintrotextиfulltext, если в настройках не отметить объединение; - не понимает шорткоды старых расширений и оставляет в тексте конструкции вида
{gallery}foto/obiekt1{/gallery}; - пропускает картинки, вставленные не тегом
<img>, а через модули и позиции шаблона.
Ручной экспорт через базу
Когда структура нетиповая, беру данные напрямую и собираю WXR-файл (это XML-формат импорта WordPress) или заливаю через WP-CLI. Выборка выглядит примерно так.
SELECT
c.id,
c.title,
c.alias,
cat.alias AS cat_alias,
c.introtext,
c.fulltext,
c.created,
c.metadesc,
c.metakey
FROM jos_content c
LEFT JOIN jos_categories cat ON cat.id = c.catid
WHERE c.state = 1
ORDER BY c.created;
Дальше скрипт на PHP или Python склеивает introtext и fulltext, чистит HTML от инлайновых стилей Joomla и заливает через wp post create. Ключевое: сохранить пару «старый id + старый alias», она потом нужна для карты редиректов. Я записываю их в мета-поля, чтобы связь не потерялась.
wp post create
--post_type=post
--post_title="Как выбрать насос"
--post_name="kak-vybrat-nasos"
--post_status=publish
--post_date="2019-04-12 10:00:00"
--post_category=7
--meta_input='{"_joomla_id":"142","_joomla_alias":"kak-vybrat-nasos"}'
--post_content="$(cat article-142.html)"
Весь перенос делаю на копии, а не на боевом домене. Технический поддомен вида new.example.ru, закрытый от индексации в robots.txt и паролем на уровне сервера. Про то, зачем нужна такая площадка и как её держать в порядке, есть заметка про staging. Открывать новый сайт индексации до момента переключения нельзя: получите дубли всего контента и разбор полётов с поиском.
Картинки и вложения: где они лежат в Joomla
В Joomla почти всё медиа живёт в /images/, разложенное по подпапкам как удобно было редактору. Плюс /media/ для файлов расширений и /attachments/ если стоял Attachments.
Импортеры скачивают только то, что нашли в HTML статей по тегу <img src>. Всё остальное остаётся в старой папке. Порядок действий, который меня ни разу не подводил:
- Скопировать
/images/целиком с сервера, до отключения старого сайта. - Дать импортеру перетащить картинки статей в медиатеку WordPress.
- Оставшийся массив залить в
/wp-content/uploads/joomla/как есть, сохранив структуру папок. - Прописать редиректы
/images/(.*)на новый путь, чтобы старые прямые ссылки и картинки в поиске по картинкам не отвалились.
Четвёртый пункт пропускают почти все. У сайтов с каталогом товаров и фотоотчётами картиночный трафик из Яндекса бывает заметной долей переходов, и терять его глупо.
RewriteEngine On
RewriteRule ^images/(.*)$ /wp-content/uploads/joomla/$1 [R=301,L]
Отдельная головная боль это PDF: прайсы, инструкции, сертификаты. Они часто лежат в /images/stories/docs/ и ссылки на них раздаются в мессенджерах и печатных материалах. Такие адреса лучше не переносить вообще, а оставить файлы по старым путям физически.
Карта редиректов: главный пункт всей затеи
Здесь теряют трафик. Контент переехал, дизайн собран, а через две недели после переключения посещаемость минус 60 процентов, потому что каждый второй старый адрес отдаёт 404.
Проблема в том, что Joomla умеет отдавать один и тот же материал по нескольким адресам сразу:
/index.php?option=com_content&view=article&id=142&catid=7/component/content/article/7-nasosy/142-kak-vybrat-nasos/nasosy/142-kak-vybrat-nasos.html(стандартный SEF с суффиксом)/nasosy/kak-vybrat-nasos.html(если стоял sh404SEF со своими правилами)
Какой из вариантов реально в индексе, по базе не поймёшь. Источники правды:
- выгрузка страниц из Яндекс Вебмастера, раздел «Страницы в поиске», там же можно скачать CSV;
- Google Search Console, отчёт по эффективности за 12 месяцев;
sitemap.xmlстарого сайта, если он был живым;- логи сервера за 30-60 дней, самый честный источник, показывает и то, что не в индексе, но по чему ходят люди;
- таблица
#__redirect_links, если владелец пользовался штатным компонентом перенаправлений.
Собираю единый список уникальных URL, дедуплицирую и раскладываю в таблицу из двух колонок: старый адрес и новый. Сотня-другая строк это нормально, полторы тысячи тоже бывает.
Дальше выбор инструмента. Плагин Redirection умеет импортировать CSV и логирует 404, что удобно первые недели. Правила в .htaccess работают быстрее, потому что отрабатывают до загрузки PHP, но редактировать их владельцу потом нельзя. Мой компромисс: массовые шаблонные правила в .htaccess, точечные исключения в плагине.
Шаблонные правила выглядят так.
# Старые SEF-адреса вида /nasosy/142-kak-vybrat-nasos.html
RewriteRule ^nasosy/[0-9]+-(.*).html$ /blog/$1/ [R=301,L]
# Точка входа Joomla с параметрами
RewriteCond %{QUERY_STRING} (^|&)id=142(&|$)
RewriteRule ^index.php$ /blog/kak-vybrat-nasos/? [R=301,L]
# Служебные адреса, которые не должны жить
RewriteRule ^component/(users|search)/ / [R=301,L]
Знак вопроса в конце цели обязателен, иначе Apache приклеит исходную строку запроса к новому адресу и получите /blog/kak-vybrat-nasos/?option=com_content&id=142. Мелочь, которая создаёт дубли на ровном месте.
После настройки прогоняю весь список автоматом и глазами смотрю на коды ответа.
while read -r url; do
code=$(curl -s -o /dev/null -w '%{http_code}' -L --max-redirs 3 "https://example.ru$url")
printf '%s %sn' "$code" "$url"
done < old-urls.txt | grep -v '^200' | tee broken.txt
Правило простое: только 301, только одним прыжком, только на существующую страницу. Цепочки из трёх редиректов и склейки всего подряд на главную поиск переваривает плохо: страница, отправленная на главную, теряет свои позиции полностью. Если точного соответствия нет, целься в ближайшую по смыслу рубрику, а не в главную. Что делать с адресами, которым замены нет вообще, разбирал в материале про битые ссылки и 404.
Чем заменить расширения Joomla
Расширения переносить нельзя, у них нет версий под WordPress. Нужны функциональные аналоги, и здесь всплывает половина скрытой стоимости переезда.
| Было в Joomla | Стало в WordPress | Комментарий |
|---|---|---|
| K2 (материалы с полями) | записи + ACF или Meta Box | поля переносятся отдельным проходом |
| RSForm Pro, Convert Forms | Contact Form 7 или своя форма | согласие на обработку ПДн настроить заново |
| sh404SEF | Rank Math или Yoast | правила ЧПУ придётся описать заново |
| Akeeba Backup | UpdraftPlus, бэкапы хостинга | сам формат JPA больше не нужен |
| Phoca Gallery | галерея Gutenberg, Envira | шорткоды в тексте чистить руками |
| VirtueMart, HikaShop | WooCommerce | самый дорогой пункт, отдельный проект |
| JComments | штатные комментарии | часто просто отключают |
| JEvents | The Events Calendar | если календарь вообще нужен |
| Falang, JoomFish | Polylang, WPML | вторая языковая версия удваивает работу |
Мой подход: половину расширений на новом сайте не воспроизводить вообще. На типовом корпоративном сайте из двадцати установленных компонентов реально используются пять, остальные ставились «на попробовать» в 2016 году и с тех пор просто грузят сервер. Инвентаризация из второго раздела как раз для этого и нужна.
Магазин это отдельная история. VirtueMart на 800 товаров с ценами, свойствами, вариантами и историей заказов не переезжает за вечер. Такое считаю отдельным проектом со своим бюджетом и сроком, а не строчкой в смете миграции.
Сколько это стоит и сколько занимает
Ориентиры по моим проектам 2025-2026 годов, без стоимости дизайна и без магазинов:
| Объём | Работа | Срок | Цена, руб. |
|---|---|---|---|
| до 50 материалов, готовая тема | импортер, редиректы, приёмка | 3-5 дней | 25 000-40 000 |
| 100-400 материалов, 10-20 рубрик | импорт, чистка HTML, карта на 300 URL | 2 недели | 45 000-90 000 |
| 1 000+ материалов, кастомные поля | ручной экспорт, скрипты, поэтапная сверка | 3-5 недель | от 120 000 |
Что обычно съедает время сверх плана: чистка HTML после старого визуального редактора (инлайновые стили, таблицы вёрстки, пустые теги <span>), сборка карты редиректов, восстановление внутренней перелинковки. Последнее особенно: ссылки внутри статей ведут на старые адреса, и после переезда каждая из них проходит через редирект. Работает, но лучше переписать их сразу на новые пути одним search-replace.
Не входит в такую смету: разработка с нуля, дизайн и редизайн, перенос интернет-магазина, написание нового контента. Это либо не мой профиль, либо отдельные задачи со своей ценой. Мои тарифы на обслуживание начинаются после переезда, когда сайт уже надо просто вести.
Приёмка: чек-лист на две недели после переезда
День переключения это не финиш. Первые две недели идёт хвост, и половина проблем всплывает именно там.
В день переключения:
- проверить, что
robots.txtбольше не закрывает сайт от индексации (забывают регулярно, это самая дорогая ошибка переезда); - убедиться, что SSL живой и HTTPS-редирект работает без цикла;
- отправить новый
sitemap.xmlв Яндекс Вебмастер и Search Console; - проверить форму заявки реальной отправкой и посмотреть, дошло ли письмо;
- проверить, что счётчик Метрики стоит на всех страницах, а цели настроены заново;
- прогнать список старых URL скриптом выше и убедиться в 301 без цепочек.
В первую неделю:
- ежедневно смотреть 404 в логах и в плагине редиректов, дописывать правила;
- сверить количество страниц в индексе, оно будет проседать, это нормально;
- проверить скорость на мобильном, старые картинки из Joomla обычно весят по 2-3 мегабайта и никогда не сжимались;
- посмотреть, не осталось ли в текстах шорткодов от старых расширений, поиском по фигурным скобкам.
Во вторую неделю:
- сверить трафик с прошлым месяцем по разделам, а не в целом по сайту, так видно, какая группа страниц просела;
- проверить, что старый хостинг ещё оплачен, ничего не отключено и база Joomla цела (месяц минимум, лучше три);
- снять первый полноценный бэкап нового сайта в стороннее хранилище.
Просадка на 10-25 процентов в первые две-три недели после смены движка это ожидаемо, поиск переиндексирует сайт постепенно. Возврат к прежним показателям при аккуратных редиректах занимает 1-2 месяца. Если через полтора месяца трафик не вернулся, ищите ошибку в редиректах или в метатегах, а не ждите. Полный список того, что проверять после смены CMS, собран в чек-листе по SEO.
Что делать прямо сейчас
Если решение о переезде уже принято, начните не с установки WordPress, а с двух вещей: полный бэкап Joomla вместе с базой и выгрузка списка проиндексированных страниц из Вебмастера. Первое спасает, когда что-то пойдёт не так, второе определяет успех всей затеи.
И не отключайте старый сайт в день запуска нового. Пусть повисит месяц на техническом поддомене: пару раз мне это спасало проект, когда обнаруживалась потерянная при импорте страница, которую владелец считал важной.
Если нужен человек, который проведёт миграцию и потом будет вести сайт дальше, напишите через форму и приложите адрес старого сайта. Обычно за день смотрю базу, считаю объём материалов и говорю точную цифру и срок, без «от» и «примерно».
Частые вопросы
Сколько стоит миграция с Joomla на WordPress
Порядка 150-300 тысяч рублей за средний сайт вместе с вёрсткой шаблона под существующий дизайн. На типовой теме заметно дешевле.
Что переносить, а что оставить
Переносить то, что приносит трафик и заявки. Перенос всего подряд раздувает смету и создаёт свалку на новом сайте: половина материалов пятнадцатилетней давности никому не нужна.
Почему падает трафик после переезда
Потому что адреса поменялись, а редиректы не настроены. Каждая старая ссылка из поиска и с чужих сайтов приводит на 404. Карта редиректов делается до переключения, а не после.
Сколько времени занимает переезд
От пары недель до полутора месяцев в зависимости от объёма. Отдельно закладывайте две недели после переключения на приёмку: именно тогда всплывают потерянные страницы и битые ссылки.