How to Force RTL on WordPress Frontend While Keeping Admin in English

Many WordPress sites need right-to-left (RTL) content for languages like Arabic, Hebrew, or Persian. However, website owners often prefer to keep their WordPress admin dashboard in English (LTR) for convenience.

By default, WordPress switches the whole site — both frontend and backend — to RTL when you choose an RTL language. Fortunately, with a little custom code, you can:

  • Force the frontend to always render in RTL.
  • Keep the WordPress admin in English (LTR).
  • Protect sliders, galleries, and hero images from breaking.
  • Ensure navigation menus and headers remain in RTL.

Below is a simple must-use plugin (mu-plugin) you can drop into your WordPress installation.


Step 1: Create the Plugin File

wp-content/mu-plugins/

(If the mu-plugins folder doesn’t exist, create it.)

Inside that folder, create a new file called:

force-rtl-frontend.php

Step 2: Add This Code

Copy and paste the following code into force-rtl-frontend.php:

<?php
/**
 * Plugin Name: Force RTL Frontend (v1.2) — English Admin
 * Description: Frontend RTL; Admin stays English (LTR). Limits LTR to slider/cover widgets only; keeps headers/menus RTL.
 * Version: 1.2
 */

/* Keep wp-admin in English only */
add_filter('locale', function ($locale) {
    return is_admin() ? 'en_US' : $locale;
}, 999);

/* Force dir="rtl" on <html> for the public site */
add_filter('language_attributes', function ($output) {
    if (is_admin()) return $output;
    $output = preg_replace('/\sdir=("|\')(rtl|ltr)\1/i', '', $output);
    return trim($output) . ' dir="rtl"';
}, 999);

/* Minimal CSS: document RTL; only specific MEDIA/SLIDER wrappers LTR; explicitly keep headers/menus RTL */
add_action('wp_enqueue_scripts', function () {
    if (is_admin()) return;

    // LTR islands — ONLY slider/cover/gallery engines
    $ltr_selectors = array(
        '.swiper, .swiper-container, .elementor-swiper, .elementor-slides',
        '.slick-slider, .slick-track',
        '.rev_slider_wrapper, .rev_slider',
        '.fusion-slider',
        '.tns-outer, .tns-slider',    // Tiny Slider
        '.splide, .splide__track',    // Splide
        '.owl-carousel, .owl-stage',  // Owl Carousel
        '.wp-block-jetpack-slideshow, .wp-block-gallery',
        '.wp-block-cover, .wp-block-cover-image'
    );

    // Headers/menus to REMAIN RTL
    $header_menu_rtl = array(
        'header',
        '.site-header',
        '.main-header',
        '.elementor-location-header',
        '.ast-header-break-point',     // Astra
        '.generatepress-header',       // GeneratePress
        '.oceanwp-header',             // OceanWP
        '.neve-main-header',           // Neve
        'nav',
        '.main-navigation',
        '.primary-navigation',
        '.menu, [class*="menu"], [class*="navigation"]'
    );

    $css = "
/* Global RTL */
html[dir=\"rtl\"], html[dir=\"rtl\"] body { direction: rtl; }

/* Keep headers and menus RTL */
" . implode(",\n", $header_menu_rtl) . " { direction: rtl !important; text-align: right; }

/* LTR islands ONLY for sliders/galleries/covers */
" . implode(",\n", $ltr_selectors) . " { direction: ltr !important; }

/* Utility class for any custom LTR block */
.force-ltr { direction: ltr !important; text-align: left !important; }

/* Basic form/text alignment */
html[dir=\"rtl\"] input, 
html[dir=\"rtl\"] textarea, 
html[dir=\"rtl\"] select { text-align: right; }
";

    wp_register_style('force-rtl-frontend-12', false);
    wp_enqueue_style('force-rtl-frontend-12');
    wp_add_inline_style('force-rtl-frontend-12', $css);
}, 10);

Step 3: Save and Refresh

  • No need to “activate” this plugin — mu-plugins load automatically.
  • Clear any caches (plugin, server, CDN) and hard-refresh your site.
  • Your frontend will now be RTL, while your WordPress admin remains in English (LTR).