Человекопонятные URL (ЧПУ, Friendly URLs) — это основа SEO-оптимизации любого сайта. MODX Revolution имеет мощную встроенную систему для создания красивых и поисковых URL вместо стандартных index.php?id=5. В этом руководстве разберем полную настройку ЧПУ для разных веб-серверов.
Что такое ЧПУ и зачем они нужны
Преимущества friendly URLs
Для SEO:
- Лучшая индексация поисковыми системами
- Ключевые слова в URL влияют на ранжирование
- Более высокий CTR в поисковой выдаче
- Простота для понимания алгоритмов поисковых систем
Для пользователей:
- Понятная структура сайта
- Возможность предугадать контент по URL
- Удобство копирования и передачи ссылок
- Лучшая навигация и юзабилити
Примеры URL до и после
Без ЧПУ:
https://site.com/index.php?id=5
https://site.com/index.php?id=15&mode=view
С ЧПУ:
https://site.com/services/
https://site.com/services/web-development/
https://site.com/blog/modx-setup-guide/
Базовая настройка ЧПУ в MODX
Системные настройки
Откройте Система → Настройки системы и найдите следующие параметры:
friendly_urls = Да
use_alias_path = Да
friendly_alias_urls = Да
allow_duplicate_alias = Нет
automatic_alias = Да
friendly_urls_strict = Да
container_suffix = /
Подробное описание настроек
friendly_urls
Значение: Да
Описание: Включает систему ЧПУ в MODX
use_alias_path
Значение: Да
Описание: Использует полный путь в URL (включая родительские страницы)
Да: /company/about/team/
Нет: /team/
friendly_alias_urls
Значение: Да
Описание: Разрешает использование алиасов в URL вместо ID
allow_duplicate_alias
Значение: Нет
Описание: Запрещает одинаковые алиасы на одном уровне
automatic_alias
Значение: Да
Описание: Автоматически генерирует алиас из заголовка страницы
friendly_urls_strict
Значение: Да
Описание: Строгое соответствие URL (предотвращает дублирование контента)
container_suffix
Значение: /
Описание: Добавляет слеш в конце URL для контейнеров
Дополнительные настройки
publish_default = Да
searchable_default = Да
richtext_default = Да
hidemenu_default = Нет
# Настройки алиасов
friendly_alias_max_length = 100
friendly_alias_lowercase_only = Да
friendly_alias_word_delimiter = -
friendly_alias_realtime = Нет
Настройка для Apache
Основной .htaccess файл
Создайте файл .htaccess в корне сайта:
# MODX supports Friendly URLs via this .htaccess file
# Ensure the RewriteEngine is turned on
RewriteEngine On
# Основные настройки для MODX
RewriteBase /
# Исключения для файлов и папок
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Исключения для системных папок
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
# Безопасность - скрытие системных файлов
<Files ".htaccess">
Order Allow,Deny
Deny from all
</Files>
<Files "config.inc.php">
Order Allow,Deny
Deny from all
</Files>
# Скрытие папки core
RewriteRule ^core/(.*)$ - [F,L]
# Скрытие служебных файлов MODX
RedirectMatch 403 /\..*$
RedirectMatch 403 core/.*
RedirectMatch 403 /config\.core\.php$
RedirectMatch 403 /config\.inc\.php$
# Принудительное использование слеша для папок
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^(.*)$ $1/ [R=301,L]
# Принудительное удаление index.php из URL
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+index\.php[\s?] [NC]
RewriteRule ^index\.php/?(.*)$ /$1 [R=301,L]
# Удаление множественных слешей
RewriteCond %{THE_REQUEST} //
RewriteRule .* /$0 [R=301,L]
# Принудительное использование www (опционально)
# RewriteCond %{HTTP_HOST} !^www\.
# RewriteCond %{HTTP_HOST} !^localhost$ [NC]
# RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Расширенная конфигурация Apache
# Дополнительные настройки производительности и безопасности
# Включение сжатия
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
</IfModule>
# Кеширование статических файлов
<IfModule mod_expires.c>
ExpiresActive on
# Изображения
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/webp "access plus 1 month"
# CSS и JavaScript
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/pdf "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType text/js "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType application/x-javascript "access plus 1 month"
# Шрифты
ExpiresByType application/x-font-ttf "access plus 1 year"
ExpiresByType font/opentype "access plus 1 year"
ExpiresByType application/x-font-woff "access plus 1 year"
ExpiresByType application/font-woff2 "access plus 1 year"
</IfModule>
# Защита от hotlinking изображений
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?yourdomain\.com [NC]
RewriteCond %{REQUEST_URI} \.(jpg|jpeg|png|gif|webp)$ [NC]
RewriteRule \.(jpg|jpeg|png|gif|webp)$ - [F]
# Блокировка вредоносных ботов
RewriteCond %{HTTP_USER_AGENT} (libwww-perl|wget|python|nikto|curl|scan|java|winhttp|clshttp|loader) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} (%0A|%0D|%27|%3C|%3E|%00) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} (;|<|>|'|"|\)|\(|%0A|%0D|%22|%27|%28|%3C|%3E|%00).*(libwww-perl|wget|python|nikto|curl|scan|java|winhttp|HTTrack|clshttp|archiver|loader|email|harvest|extract|grab|miner) [NC]
RewriteRule .* - [F]
Настройка для поддоменов
# Если сайт находится в подпапке
RewriteBase /subfolder/
# Или для поддомена
RewriteCond %{HTTP_HOST} ^subdomain\.example\.com$ [NC]
RewriteRule ^(.*)$ /subdomain/$1 [L]
Настройка для Nginx
Основная конфигурация Nginx
server {
listen 80;
server_name example.com www.example.com;
root /var/www/html;
index index.php index.html;
# Логи
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
# Основное правило для MODX friendly URLs
location / {
try_files $uri $uri/ @modx-rewrite;
}
location @modx-rewrite {
rewrite ^/(.*)$ /index.php?q=$1 last;
}
# Обработка PHP файлов
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; # или 127.0.0.1:9000
fastcgi_index index.php;
}
# Запрет доступа к служебным файлам
location ~ /\. {
deny all;
}
location ~* ^/(core|config\.inc\.php|config\.core\.php) {
deny all;
return 403;
}
# Оптимизация статических файлов
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|webp|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# Принудительный слеш для папок
location ~ ^/[^.]*[^/]$ {
return 301 $scheme://$host$uri/;
}
}
HTTPS конфигурация для Nginx
server {
listen 80;
server_name example.com www.example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
return 301 https://www.example.com$request_uri;
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;
}
server {
listen 443 ssl http2;
server_name www.example.com;
root /var/www/html;
index index.php index.html;
# SSL настройки
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
# HSTS заголовок
add_header Strict-Transport-Security "max-age=31536000" always;
# Основные правила MODX
location / {
try_files $uri $uri/ @modx-rewrite;
}
location @modx-rewrite {
rewrite ^/(.*)$ /index.php?q=$1 last;
}
# PHP обработка
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS on;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
# Увеличение лимитов для больших форм
fastcgi_read_timeout 300;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
}
# Безопасность
location ~ /\. {
deny all;
}
location ~* ^/(core|config\.inc\.php|config\.core\.php|\.ht) {
deny all;
return 403;
}
# Кеширование и сжатие
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|webp|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
# Сжатие для текстовых файлов
gzip_static on;
}
}
Расширенная Nginx конфигурация
# Включение в основной nginx.conf или в server блоке
# Сжатие
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/xml+rss
application/json;
# Безопасность заголовков
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
# Ограничение размера загружаемых файлов
client_max_body_size 50M;
# Таймауты
client_body_timeout 60;
client_header_timeout 60;
keepalive_timeout 10 10;
send_timeout 60;
# Лимиты подключений
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;
location /manager/ {
limit_req zone=login burst=5 nodelay;
# остальные правила для админки
}
Специальные случаи настройки
Мультисайтовая конфигурация
# .htaccess для нескольких сайтов на одном домене
RewriteEngine On
RewriteBase /
# Сайт 1 в подпапке /site1/
RewriteCond %{HTTP_HOST} ^site1\.example\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/site1/
RewriteRule ^(.*)$ /site1/$1 [L]
# Сайт 2 в подпапке /site2/
RewriteCond %{HTTP_HOST} ^site2\.example\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/site2/
RewriteRule ^(.*)$ /site2/$1 [L]
# Основной сайт
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
Поддержка нескольких языков
# Автоматическое определение языка
RewriteCond %{HTTP:Accept-Language} ^ru [NC]
RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^(.*)$ /ru/ [R=302,L]
RewriteCond %{HTTP:Accept-Language} ^en [NC]
RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^(.*)$ /en/ [R=302,L]
# По умолчанию английский
RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^(.*)$ /en/ [R=302,L]
Диагностика и решение проблем
Проверка работы ЧПУ
- Проверьте системные настройки в MODX
- Убедитесь в наличии .htaccess (для Apache)
- Проверьте права доступа к файлам конфигурации
- Включите отладку в MODX
Типичные проблемы и решения
Ошибка 404 на всех страницах
Причина: Неправильная настройка RewriteBase или путей
Решение:
# Если сайт в подпапке
RewriteBase /subfolder/
# Если в корне
RewriteBase /
Бесконечные редиректы
Причина: Конфликт правил в .htaccess
Решение:
# Добавьте условие для предотвращения зацикливания
RewriteCond %{ENV:REDIRECT_STATUS} !^$
RewriteRule ^.*$ - [L]
ЧПУ работают, но страницы загружаются медленно
Причина: Неоптимальные правила rewrite
Решение:
# Добавьте исключения для существующих файлов
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
Проблемы с кириллицей в URL
Настройка в MODX:
friendly_alias_translit = iconv
friendly_alias_translit_class = translit.modTransliterate
friendly_alias_translit_class_path = {core_path}components/
Дубли страниц с www и без
Для Apache:
# Принудительное www
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Для Nginx:
# Редирект на www
server {
listen 80;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
Отладка ЧПУ
Включите отладку в MODX:
# Системные настройки
log_level = MODX_LOG_LEVEL_INFO
log_target = FILE
# В .htaccess добавьте для отладки
RewriteEngine On
RewriteLog /var/log/apache2/rewrite.log
RewriteLogLevel 3
Проверьте логи:
- Apache:
/var/log/apache2/error.log - Nginx:
/var/log/nginx/error.log - MODX:
core/cache/logs/
SEO-оптимизация ЧПУ
Правила создания SEO-дружелюбных URL
- Используйте ключевые слова в URL
- Делайте URL короткими (до 60 символов)
- Используйте дефисы вместо подчеркиваний
- Избегайте спецсимволов и чисел
- Создавайте логичную иерархию
Автоматизация создания алиасов
Создайте плагин для автогенерации алиасов:
<?php
// Событие: OnDocFormSave
switch($modx->event->name) {
case 'OnDocFormSave':
if(empty($resource->get('alias'))) {
// Генерация алиаса из заголовка
$alias = $modx->filterPathSegment($resource->get('pagetitle'));
// Транслитерация
$alias = $modx->runSnippet('Translit', array('str' => $alias));
// Проверка уникальности
$count = 1;
$original_alias = $alias;
while($modx->getCount('modResource', array('alias' => $alias, 'parent' => $resource->get('parent')))) {
$alias = $original_alias . '-' . $count;
$count++;
}
$resource->set('alias', $alias);
}
break;
}
?>
Мониторинг SEO-показателей
Больше о SEO-продвижении MODX сайтов можно узнать в статье SEO и продвижение сайтов на MODX.
// Плагин для отслеживания изменений URL
switch($modx->event->name) {
case 'OnDocFormSave':
$old_uri = $resource->get('uri');
// После сохранения проверяем изменение URI
if($old_uri !== $resource->get('uri')) {
// Создание 301 редиректа
$redirect = $modx->newObject('Redirect');
$redirect->set('pattern', $old_uri);
$redirect->set('target', $resource->get('uri'));
$redirect->set('http_response_code', 301);
$redirect->save();
}
break;
}
Продвинутые техники
Динамические URL на основе TV полей
// Плагин для создания URL на основе TV
switch($modx->event->name) {
case 'OnDocFormSave':
if($resource->get('template') == 5) { // Шаблон товара
$brand = $resource->getTVValue('brand');
$model = $resource->getTVValue('model');
if($brand && $model) {
$alias = strtolower($brand . '-' . $model);
$alias = preg_replace('/[^a-z0-9\-]/', '', $alias);
$resource->set('alias', $alias);
}
}
break;
}
Кастомные правила маршрутизации
// Создание кастомного роутера
$modx->map->add('Route', array(
'class' => 'CustomRoute',
'path' => '/catalog/{category}/{product}/',
'handler' => 'CatalogHandler'
));
class CatalogHandler {
public function handle($category, $product) {
// Логика обработки маршрута
$categoryId = $this->getCategoryByAlias($category);
$productId = $this->getProductByAlias($product, $categoryId);
if($productId) {
$modx->sendRedirect($modx->makeUrl($productId));
} else {
$modx->sendErrorPage();
}
}
}
Заключение
Правильная настройка ЧПУ в MODX — это фундамент успешного SEO-продвижения сайта. Система friendly URLs в MODX предоставляет гибкие возможности для создания красивых и поисково-оптимизированных адресов.
Ключевые моменты:
- Включите все необходимые системные настройки в MODX
- Настройте корректный .htaccess для Apache или конфигурацию Nginx
- Протестируйте работу на всех типах страниц
- Настройте 301-редиректы при изменении URL
- Мониторьте производительность и SEO-показатели
Безопасность:
- Ограничьте доступ к служебным файлам
- Используйте HTTPS
- Настройте защиту от ботов и спама
Производительность:
- Включите сжатие и кеширование
- Оптимизируйте правила rewrite
- Настройте CDN для статических файлов
ЧПУ в MODX — это не просто красивые URL, а мощный инструмент для улучшения пользовательского опыта и поисковой оптимизации вашего сайта.
Читайте также: Относительные ссылки в MODX: как одна настройка создаёт сотни 404 — разбираю, почему link_tag_scheme = -1 ломает навигацию на вложенных страницах.