Skip to main content

Redirect Chain & Loop Analysis

Issue No: 104

Category: HTML Head Tags

Issue type: Issue

Priority: Critical

Description

The crawler checks whether the page includes a <meta name="viewport" content="width=device-width, initial-scale=1"> tag inside the <head> element. This tag is required for correct mobile rendering and is a prerequisite for Google's mobile-friendliness evaluation under mobile-first indexing.

How do we capture it

  1. Fetch the raw HTML response by sending an HTTP GET request to the target page URL and reading the full response body as raw text.

  2. Isolate the <head> section by locating content between the opening <head> and closing </head> tags in the raw HTML. Only inspect tags found within this range; a viewport tag placed outside <head> is treated as absent since browsers ignore it in that position.

  3. Search for a viewport meta tag within the <head> content using a case-insensitive pattern match:

    • Match any <meta> element where the name attribute equals viewport (case-insensitive, with or without quotes).
    • Example pattern: <meta[^>]+name=["']?viewport["']?[^>]*> — also apply name-last ordering since some pages place content before name.
  4. Record tag presence:

    • Set has_viewport_meta = true if at least one matching <meta name="viewport"> element is found inside <head>.
    • Set has_viewport_meta = false if no matching element is found.
  5. Extract the content attribute value from the first matched tag:

    • Locate the content="..." attribute within the matched tag string.
    • Strip surrounding quotes and store the raw value as viewport_content.
    • If no tag is found, store null.
  6. Check for width=device-width:

    • Perform a case-insensitive substring search of viewport_content for width=device-width.
    • Set has_width_device_width = true if found, otherwise false.
  7. Check for initial-scale=1:

    • Perform a case-insensitive substring search of viewport_content for initial-scale=1.
    • Allow for optional whitespace around the = sign.
    • Set has_initial_scale_1 = true if found, otherwise false.
  8. Count all viewport meta tags inside <head>:

    • Count every occurrence of <meta name="viewport"> within the isolated <head> content.
    • If the count is greater than 1, set has_multiple_viewport_tags = true.

What to store

FieldTypeComment
site_idintegerFK → sites(id)
page_urltextThe URL of the page inspected
has_viewport_metabooleanWhether a <meta name="viewport"> tag was found inside <head> in the raw HTML
viewport_contenttextThe raw value of the content attribute from the first viewport meta tag; null if the tag is absent
has_width_device_widthbooleanWhether the viewport content value contains width=device-width
has_initial_scale_1booleanWhether the viewport content value contains initial-scale=1
has_multiple_viewport_tagsbooleanWhether more than one <meta name="viewport"> tag is present inside <head>
detected_attimestampWhen this data was last captured during a crawl

Condition for trigger

The following rules evaluate stored fields and produce diagnostics in the audit report.

  • Trigger Rule 1: Viewport Meta Tag Missing

    • Target Field: has_viewport_meta
    • Evaluation Logic: has_viewport_meta = false
    • Severity: CRITICAL
    • Diagnostic Message: "The page at [page_url] is missing a <meta name='viewport'> tag inside <head>. Without this tag, mobile browsers render the page at a fixed desktop-equivalent width and scale it down, producing an unreadable zoomed-out layout. Google also uses this tag as a mobile-friendliness signal under mobile-first indexing. Add <meta name='viewport' content='width=device-width, initial-scale=1'> inside the <head> element."
  • Trigger Rule 2: Viewport Tag Missing width=device-width

    • Target Field: has_width_device_width
    • Evaluation Logic: has_viewport_meta = true AND has_width_device_width = false
    • Severity: CRITICAL
    • Diagnostic Message: "The viewport meta tag on [page_url] does not include width=device-width. The current content value is [viewport_content]. Without this directive the browser does not match the layout width to the device screen width. Update the viewport tag so that its content attribute includes width=device-width."
  • Trigger Rule 3: Viewport Tag Missing initial-scale=1

    • Target Field: has_initial_scale_1
    • Evaluation Logic: has_viewport_meta = true AND has_initial_scale_1 = false
    • Severity: WARNING
    • Diagnostic Message: "The viewport meta tag on [page_url] does not include initial-scale=1. The current content value is [viewport_content]. Without this directive some browsers apply a non-standard zoom level on initial page load. Update the viewport tag to include initial-scale=1."
  • Trigger Rule 4: Multiple Viewport Tags Detected

    • Target Field: has_multiple_viewport_tags
    • Evaluation Logic: has_multiple_viewport_tags = true
    • Severity: WARNING
    • Diagnostic Message: "More than one <meta name='viewport'> tag was found in the <head> of [page_url]. Browsers typically apply only the last tag encountered, which may not be the intended configuration. Consolidate all viewport directives into a single tag with the correct content value."

Sources

Long description

The viewport meta tag is an HTML directive placed inside the <head> element that instructs the browser how to scale and display the page on different screen sizes. Its canonical form is:

<meta name="viewport" content="width=device-width, initial-scale=1">

Before this tag was introduced, mobile browsers rendered pages at a fixed desktop-equivalent width (typically 980 px) and then scaled the entire layout down to fit the physical screen. This produced a zoomed-out, unreadable page that required pinch-to-zoom to interact with. The viewport meta tag addresses this by instructing the browser to match the layout width to the device screen width (width=device-width) and to start at a 1:1 zoom level (initial-scale=1).

Why it matters for SEO

Google completed the transition to mobile-first indexing for all sites in 2023. Googlebot now primarily crawls and evaluates the mobile version of a page. The presence of width=device-width in the viewport meta tag is one of the explicit signals evaluated by Google's mobile-friendliness pipeline. Pages that fail this check are flagged in Google Search Console under the Mobile Usability report and may receive lower scores for mobile-specific ranking factors. A missing or misconfigured viewport tag can prevent a page from being classified as mobile-friendly regardless of how the page visually renders.

Crawler capture notes

The XeoPix crawler inspects raw HTTP response bytes only. The <meta name="viewport"> tag must be present as static HTML in the server response to be detected. If the tag is injected by JavaScript after the page loads, the crawler will not detect it and will record has_viewport_meta = false. Sites using server-side rendering (SSR) return the tag in the initial HTML response and are correctly handled. Client-side-only rendering frameworks that inject the viewport tag via JavaScript after load cannot be verified by this crawler; the constraint applies equally to all JavaScript-injected head tags.

Common failures the crawler checks:

  • The viewport meta tag is entirely absent from the page <head>.
  • The viewport tag uses a fixed pixel width such as width=1024 instead of width=device-width, causing the layout to ignore the device screen width.
  • The initial-scale directive is missing, causing some browsers to apply a non-standard zoom factor on initial load.
  • The viewport tag is present on the desktop template but absent from a separate mobile-specific template served at the same URL.
  • Multiple conflicting <meta name="viewport"> tags exist inside <head>; browsers typically apply the last one encountered, which may differ from the intended configuration.
  • The viewport tag is placed outside <head> (e.g. inside <body>), which causes browsers to ignore it.

How to Fix

  1. Add the viewport meta tag if missing: place <meta name="viewport" content="width=device-width, initial-scale=1"> inside the <head> element of every page, as close to the top of <head> as practical, before any stylesheets or scripts that depend on viewport dimensions.

  2. Correct an invalid content value: if the tag is present but does not include width=device-width, update the content attribute to include it. Remove any fixed-pixel width declarations such as width=980 or width=1024.

  3. Add initial-scale=1 if absent: if initial-scale is missing or set to a value other than 1, update the tag to include initial-scale=1 alongside width=device-width.

  4. Remove duplicate viewport tags: if more than one <meta name="viewport"> is present, consolidate them into a single tag with the correct and complete content value. Ensure no template partials or layout fragments emit their own independent viewport tags.

  5. Confirm the tag is in the server response: verify using a raw HTTP request (e.g. curl -s {url} | grep -i viewport) that the tag appears in the initial HTML before any JavaScript execution. If it is absent from the raw response but visible in a browser, the tag is being injected by JavaScript and must be moved to the server-rendered HTML.


Validation checklist

Before marking this issue resolved, confirm all of the following:

  • A single <meta name="viewport"> tag is present inside <head> in the raw HTML response.
  • The content attribute value includes width=device-width.
  • The content attribute value includes initial-scale=1.
  • No duplicate <meta name="viewport"> tags exist in <head>.
  • The tag is confirmed present in the raw HTTP response, not only after JavaScript execution.
  • Google Search Console Mobile Usability report shows no "Viewport not configured" errors for the page.