Skip to Content

RTL language without dir="rtl" on the html element

What Is This Issue

RTL dir=“rtl” on <html> for Arabic/Hebrew/Persian Content

This issue checks whether pages serving right-to-left (RTL) languages such as Arabic, Hebrew, or Persian have the dir="rtl" attribute on the root <html> element so browsers and search engines correctly interpret text directionality, layout, and reading order.

What This Issue Checks

The audit verifies that web pages declaring RTL languages (Arabic, Hebrew, Persian, etc.) in the lang attribute also include dir="rtl" on the <html> element to ensure proper text rendering and layout.

What is Considered a Passing Implementation

Your website passes this check when:

  • Pages with RTL language codes (ar, he, fa, ur, yi, ps, sd) have dir="rtl" on the <html> element
  • The dir attribute is set to "rtl" (not "ltr" or "auto") for RTL languages
  • The dir attribute is on the <html> element (not just on <body>)

Real-World Example

Passing Implementation:

<!DOCTYPE html> <html lang="ar" dir="rtl"> <head> <meta charset="UTF-8" /> <title>موقع عربي</title> </head> <body> <p>مرحبا بالعالم</p> </body> </html>

Failing Implementation:

<!-- Missing dir attribute --> <html lang="ar"> <!-- or --> <!-- Wrong direction --> <html lang="ar" dir="ltr"></html> </html>

Why Is This Important

Impact on SEO

Crawlability

While the dir attribute doesn’t directly affect crawlability, properly rendered RTL pages ensure that search engine crawlers can correctly parse and understand the content structure and layout.

Indexability

Search engines need to understand the language and text direction of your content. Missing dir="rtl" can cause search engines to misinterpret the content structure, potentially affecting how the page is indexed for RTL language searches.

Rankings

RTL language pages that render incorrectly due to missing dir="rtl" create poor user experience, leading to higher bounce rates and lower engagement signals. This can negatively impact rankings in RTL language search results.

User Experience

The dir="rtl" attribute is critical for proper text rendering:

  • Without it, RTL text appears left-to-right instead of right-to-left
  • Punctuation, numbers, and mixed-script paragraphs render incorrectly
  • Page layout (sidebars, navigation, forms) doesn’t mirror for RTL reading
  • This creates a very poor experience for Arabic, Hebrew, and Persian readers

Duplicate Content

While not directly related to duplicate content, improperly rendered RTL pages may be viewed as low-quality pages, which can affect how search engines evaluate and rank your content.

AI Search / AEO

As AI-powered search becomes more prevalent, properly structured RTL pages help AI understand your content’s language and text direction, ensuring accurate representation in AI-generated answers for RTL language users.

How Resolving This Issue Improves SEO Health Score

Fixing RTL dir attribute issues improves your overall SEO health score by:

  • Ensuring proper rendering of RTL language content
  • Improving user experience for Arabic, Hebrew, and Persian visitors
  • Reducing bounce rates from incorrectly rendered RTL pages
  • Strengthening your website’s international SEO signals for RTL languages
  • Ensuring search engines correctly interpret RTL content structure

How XeoPix Detects This

XeoPix checks whether pages serving right-to-left (RTL) languages have the dir="rtl" attribute on the root <html> element to ensure proper text rendering and layout.

Detection Process

XeoPix follows these logical steps to identify missing or incorrect dir attributes on RTL language pages:

1. Fetch the Page HTML

XeoPix issues an HTTP GET request to the target URL and reads the raw HTML response without JavaScript execution.

2. Extract the Opening <html> Tag

XeoPix parses the raw HTML to extract the opening <html> tag, which contains the lang and dir attributes.

3. Read the lang Attribute

XeoPix reads the value of the lang attribute from the <html> element to determine the declared language of the page.

4. Check if Language is RTL

XeoPix checks whether the declared lang value maps to a known RTL language:

  • Arabic: ar
  • Hebrew: he
  • Persian/Farsi: fa
  • Urdu: ur
  • Yiddish: yi
  • Pashto: ps
  • Sindhi: sd

5. Read the dir Attribute

If the page declares an RTL language, XeoPix reads the dir attribute from the <html> tag to check if it’s present and set correctly.

6. Validate dir Attribute Value

XeoPix checks the value of the dir attribute:

  • rtl — Correct for RTL languages
  • ltr — Incorrect (explicitly wrong direction)
  • auto — Not recommended for RTL languages
  • Absent — Missing (will trigger the issue)

When the Issue is Flagged

The issue is flagged when any of these conditions are met:

  • RTL language without dir=“rtl”: The page declares an RTL language (lang attribute) but doesn’t include dir="rtl" on the <html> element (either absent or set to wrong value)
  • dir explicitly set to ltr: The <html> element explicitly declares dir="ltr" while the page language is RTL (this overrides browser defaults and forces incorrect rendering)

When the Issue Passes

The issue passes when:

  • The page doesn’t declare an RTL language (no check needed)
  • The page declares an RTL language AND has dir="rtl" on the <html> element
  • The dir attribute value is exactly "rtl" (not "ltr" or "auto")

How To Fix

Practical Recommendations

1. Add dir=“rtl” to <html> Element for RTL Languages

Ensure that all pages serving RTL languages have the dir="rtl" attribute on the root <html> element.

Implementation:

<!DOCTYPE html> <html lang="ar" dir="rtl"> <head> <meta charset="UTF-8" /> <title>صفحة عربية</title> </head> <body> <!-- Page content --> </body> </html>

2. Use Correct RTL Language Codes

Ensure the lang attribute uses the correct ISO 639-1 codes for RTL languages:

LanguageISO 639-1 Code
Arabicar
Hebrewhe
Persian (Farsi)fa
Urduur
Yiddishyi
Pashtops
Sindhisd

3. Place dir Attribute on <html>, Not Just <body>

While dir on <body> can work, it’s best practice to place it on the <html> element to ensure all page content renders correctly.

Preferred:

<html lang="ar" dir="rtl"></html>

Acceptable but not optimal:

<html lang="ar"> <body dir="rtl"></body> </html>

4. Don’t Use dir=“ltr” for RTL Languages

Never set dir="ltr" on pages with RTL language codes. This explicitly forces incorrect left-to-right rendering.

Wrong:

<html lang="he" dir="ltr"> <!-- Incorrect! --> </html>

Correct:

<html lang="he" dir="rtl"></html>

5. Test RTL Rendering

After adding dir="rtl", test the page in a browser to ensure:

  • Text flows from right to left
  • Punctuation appears correctly
  • Layout mirrors appropriately (sidebars, navigation)
  • Forms and UI elements align correctly

Priority Order

  1. First: Add missing dir="rtl" to all RTL language pages
  2. Second: Fix any pages with dir="ltr" incorrectly set for RTL languages
  3. Third: Move dir attribute from <body> to <html> if needed
  4. Fourth: Verify all RTL language codes are correct in the lang attribute

What We Store

Storage Level

Page Level


Database Table / Prisma Model

PageInternationalSeo


Stored Fields

FieldTypeDescription
hasLanguageSpecificUrlsBoolean?Whether language-specific URLs exist
htmlDirString?The HTML direction attribute

Detection Dependencies

  • HTML Document
  • HTTP Response Headers

Examples

Example 1: RTL Page Missing dir Attribute

Scenario

An Arabic language page doesn’t have the dir attribute on the <html> element.

Problematic State (Fails)

<!DOCTYPE html> <html lang="ar"> <head> <meta charset="UTF-8" /> <title>موقع عربي</title> </head> <body> <p>مرحبا بالعالم</p> </body> </html>

Result: Browsers default to ltr (left-to-right) rendering. Arabic text appears in the correct Unicode order but is laid out from left to right, making it difficult to read.

Corrected State (Passes)

<!DOCTYPE html> <html lang="ar" dir="rtl"> <head> <meta charset="UTF-8" /> <title>موقع عربي</title> </head> <body> <p>مرحبا بالعالم</p> </body> </html>

Result: Browsers render text correctly from right to left, with proper layout mirroring.


Example 2: dir Set to ltr on RTL Language Page

Scenario

A Hebrew language page explicitly sets dir="ltr" on the <html> element.

Problematic State (Fails)

<!DOCTYPE html> <html lang="he" dir="ltr"> <head> <meta charset="UTF-8" /> <title>אתר בעברית</title> </head> <body> <p>שלום עולם</p> </body> </html>

Result: The browser explicitly renders the page as left-to-right, overriding any default RTL behavior. Hebrew text appears incorrectly ordered.

Corrected State (Passes)

<!DOCTYPE html> <html lang="he" dir="rtl"> <head> <meta charset="UTF-8" /> <title>אתר בעברית</title> </head> <body> <p>שלום עולם</p> </body> </html>

Result: Hebrew text renders correctly from right to left.


Example 3: dir Only Set on Body, Not html

Scenario

A Persian language page has dir="rtl" on the <body> element but not on the <html> element.

Problematic State (Not Optimal)

<!DOCTYPE html> <html lang="fa"> <head> <meta charset="UTF-8" /> <title>وبسایت فارسی</title> </head> <body dir="rtl"> <p>سلام دنیا</p> </body> </html>

Result: While this may work partially, it’s not the best practice. Some layout and text direction may not render correctly.

Corrected State (Passes)

<!DOCTYPE html> <html lang="fa" dir="rtl"> <head> <meta charset="UTF-8" /> <title>وبسایت فارسی</title> </head> <body> <p>سلام دنیا</p> </body> </html>

Result: The dir="rtl" on the <html> element ensures all page content renders correctly for RTL languages.

Unit Test

Test File

__tests__/seo-audit-checks/internationalSeo/issue-170-rtl-dir-rtl.test.js

Purpose

This unit test validates that the RTL_DIR_RTL issue is correctly detected when a page serves a right-to-left (RTL) language but the <html> element is missing the dir="rtl" attribute.

Tested Function

runInternationalSeo(ctx) from toggleGroups/internationalSeo.js

Issue Information

  • Issue Number: 170
  • Issue Code: rtl_dir_rtl
  • Toggle Group: internationalSeo

Test Scenarios

Positive Test Cases

  • Should not detect RTL_DIR_RTL when an RTL language (Arabic) is present and dir="rtl" is set on the <html> element
  • Should not detect RTL_DIR_RTL for non-RTL languages (en, es, fr) with dir="ltr"

Negative Test Cases

  • Should detect RTL_DIR_RTL when an RTL language (Arabic) is present but dir is set to "ltr"
  • Should detect RTL_DIR_RTL when the dir attribute is missing from <html> for an RTL language (Hebrew)
  • Should detect RTL_DIR_RTL for all RTL languages (ar, he, fa, ur) when dir is not set to "rtl"

Edge Cases

  • Missing dir attribute: No dir attribute on <html> with an RTL language — should detect the issue
  • All RTL languages: Iterates through all known RTL languages (ar, he, fa, ur) — each should trigger the issue when dir is not "rtl"
  • Non-RTL languages: LTR languages (en, es, fr) should not trigger the issue
  • Empty HTML: No hreflang tags — should not detect the issue

Expected Outcome

Pass

The issue should be reported when the page declares an RTL language (ar, he, fa, ur) via hreflang tags but the <html> element does not have dir="rtl".

Fail

The issue should not be reported when:

  • dir="rtl" is correctly set on <html> for RTL languages
  • Only non-RTL (LTR) languages are present
  • No hreflang tags exist

Validation

The unit test verifies:

  • Correct detection for all RTL languages (ar, he, fa, ur)
  • No false positives when dir="rtl" is correctly set
  • No false positives for non-RTL languages
  • Detection when dir attribute is entirely missing
  • Correct issue code assignment
  • Metadata (details) is included when the issue is detected
  • toggleGroups/internationalSeo.js — contains runInternationalSeo()
  • issueCodes.js — defines RTL_DIR_RTL issue code constant

Coverage Summary

  • Covers all four RTL languages (ar, he, fa, ur)
  • Verifies both presence and absence of dir="rtl"
  • Covers missing dir attribute scenario
  • Excludes non-RTL languages from false positives
  • Validates metadata presence on detection

References

Last updated on