Skip to main content

Social & Open Graph Analysis

Issue No: 97

Category: Social & Open Graph

Issue type: Issue

Priority: CRITICAL

Description

Issue 97 is the umbrella bundle for the full Social & Open Graph toggle group. It validates all 13 script-checkable items together (97, 99, 119-129) so OG, article, and Twitter metadata are evaluated as one consolidated social metadata health check.

Missing, empty, or invalid tags reduce preview quality, weaken trust signals, and can lower click-through rate from social surfaces.

How do we capture it

  1. Request final page HTML after redirects (store final URL and status).
  2. Parse head metadata from raw response HTML (no JS execution).
  3. Extract all social metadata tags:
  • meta[property] where property starts with og: or article:
  • meta[name] where name starts with twitter:
  1. Normalize keys to lowercase and trim whitespace from content.
  2. Build property maps:
    • first non-empty value per property
    • all raw values list per property
    • duplicate-property list where count > 1
  3. Validate issue-specific rules for all 13 Social & Open Graph checklist items:
  • 97, 99, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129
  1. For URL fields (og:url, og:image) validate absolute scheme and URL syntax.
  2. For datetime fields (article:published_time, article:modified_time) validate parseable ISO-8601-like format.
  3. For image dimension fields (og:image:width, og:image:height) validate positive integers.
  4. For article-only fields (article:*) evaluate only when page is article-like (og:type = article or URL/content heuristics mark it as article).
  5. Persist normalized values, validation booleans, missing/empty arrays, duplicates, and issue flags.

What to store

FieldTypeComment
has_open_graph_tagsBOOLEANTrue when at least one og:* tag exists.
has_article_open_graph_tagsBOOLEANTrue when at least one article:* property exists.
og_titleTEXTNormalized first non-empty og:title value.
og_descriptionTEXTNormalized first non-empty og:description value.
og_typeTEXTNormalized first non-empty og:type value.
og_urlTEXTNormalized first non-empty og:url value.
og_imageTEXTNormalized first non-empty og:image value.
og_image_widthTEXTNormalized first non-empty og:image:width value.
og_image_heightTEXTNormalized first non-empty og:image:height value.
og_image_altTEXTNormalized first non-empty og:image:alt value.
og_site_nameTEXTNormalized first non-empty og:site_name value.
og_localeTEXTNormalized first non-empty og:locale value.
article_published_timeTEXTRaw normalized article:published_time value.
article_modified_timeTEXTRaw normalized article:modified_time value.
article_authorTEXTRaw normalized article:author value (author attribution).
article_sectionTEXTRaw normalized article:section value.
article_tagsTEXT[]All normalized article:tag values (deduplicated).
twitter_siteTEXTNormalized first non-empty twitter:site value.
twitter_creatorTEXTNormalized first non-empty twitter:creator value.
twitter_image_altTEXTNormalized first non-empty twitter:image:alt value.
has_twitter_card_tagsBOOLEANTrue when at least one twitter:* tag exists.
og_required_tags_presentBOOLEANTrue when all core OG fields are present and non-empty.
og_missing_required_tagsTEXT[]Missing required OG fields list.
og_empty_required_tagsTEXT[]Required OG fields that exist but are empty.
og_url_is_validBOOLEANTrue when og:url is an absolute HTTP/HTTPS URL.
og_image_is_validBOOLEANTrue when og:image is an absolute URL.
og_image_width_is_validBOOLEANTrue when og:image:width is a positive integer.
og_image_height_is_validBOOLEANTrue when og:image:height is a positive integer.
og_locale_is_validBOOLEANTrue when locale matches expected pattern like en_US.
article_published_time_is_validBOOLEANTrue when published time is parseable datetime.
article_modified_time_is_validBOOLEANTrue when modified time is parseable datetime.
article_author_is_presentBOOLEANTrue when article:author exists and is not blank.
article_section_is_presentBOOLEANTrue when article:section exists and is not blank.
article_tag_is_presentBOOLEANTrue when at least one non-empty article:tag exists.
twitter_site_is_presentBOOLEANTrue when twitter:site exists and is not blank.
twitter_creator_is_presentBOOLEANTrue when twitter:creator exists and is not blank.
twitter_image_alt_is_presentBOOLEANTrue when twitter:image:alt exists and is not blank.
is_article_like_pageBOOLEANClassifier for applying article-specific rules.
og_duplicates_jsonJSONBMap of duplicate OG/article properties with all detected values.
twitter_duplicates_jsonJSONBMap of duplicate twitter properties with all detected values.
social_meta_snapshot_jsonJSONBFull normalized snapshot of parsed OG/article key-values for diagnostics.
social_missing_tags_by_issue_jsonJSONBMissing/empty fields grouped by issue ID.
social_invalid_fields_by_issue_jsonJSONBInvalid fields grouped by issue ID.
social_og_bundle_issue_detectedBOOLEANTrue when any issue in this bundle is triggered.

Condition for trigger

Conditions on database fields triggering issues.

  • Trigger Rule 97: Open Graph tags set (bundle baseline)

    • Target Field: has_open_graph_tags
    • Evaluation Logic: has_open_graph_tags = FALSE OR og_required_tags_present = FALSE
    • Severity: IMPORTANT
    • Diagnostic Message: "Open Graph baseline tags are missing or incomplete."
  • Trigger Rule 99: Twitter Card meta tags

    • Target Field: has_twitter_card_tags
    • Evaluation Logic: has_twitter_card_tags = FALSE
    • Severity: STANDARD
    • Diagnostic Message: "Twitter Card metadata layer is not implemented."
  • Trigger Rule 119: og:image:width and og:image:height missing/invalid

    • Target Field: og_image_width, og_image_height
    • Evaluation Logic: og_image IS NOT NULL AND (og_image_width IS NULL OR btrim(og_image_width) = '' OR og_image_height IS NULL OR btrim(og_image_height) = '' OR og_image_width_is_valid = FALSE OR og_image_height_is_valid = FALSE)
    • Severity: IMPORTANT
    • Diagnostic Message: "OG image dimensions are missing or invalid."
  • Trigger Rule 120: og:locale missing/invalid

    • Target Field: og_locale
    • Evaluation Logic: og_locale IS NULL OR btrim(og_locale) = '' OR og_locale_is_valid = FALSE
    • Severity: IMPORTANT
    • Diagnostic Message: "OG locale metadata is missing or malformed."
  • Trigger Rule 121: og:site_name missing

    • Target Field: og_site_name
    • Evaluation Logic: og_site_name IS NULL OR btrim(og_site_name) = ''
    • Severity: IMPORTANT
    • Diagnostic Message: "OG site name metadata is missing."
  • Trigger Rule 122: og:image:alt missing

    • Target Field: og_image_alt
    • Evaluation Logic: og_image IS NOT NULL AND (og_image_alt IS NULL OR btrim(og_image_alt) = '')
    • Severity: IMPORTANT
    • Diagnostic Message: "OG image exists without alternative text metadata."
  • Trigger Rule 123: article:published_time missing/invalid

    • Target Field: article_published_time
    • Evaluation Logic: is_article_like_page = TRUE AND (article_published_time IS NULL OR btrim(article_published_time) = '' OR article_published_time_is_valid = FALSE)
    • Severity: IMPORTANT
    • Diagnostic Message: "Article publish timestamp metadata is missing or invalid."
  • Trigger Rule 124: article:modified_time missing/invalid

    • Target Field: article_modified_time
    • Evaluation Logic: is_article_like_page = TRUE AND (article_modified_time IS NULL OR btrim(article_modified_time) = '' OR article_modified_time_is_valid = FALSE)
    • Severity: IMPORTANT
    • Diagnostic Message: "Article modified timestamp metadata is missing or invalid."
  • Trigger Rule 125: article:author missing/invalid

    • Target Field: article_author
    • Evaluation Logic: is_article_like_page = TRUE AND (article_author IS NULL OR btrim(article_author) = '' OR article_author_is_present = FALSE)
    • Severity: STANDARD
    • Diagnostic Message: "Article author attribution metadata is missing."
  • Trigger Rule 126: article:section and article:tag missing

    • Target Field: article_section, article_tags
    • Evaluation Logic: is_article_like_page = TRUE AND ((article_section IS NULL OR btrim(article_section) = '' OR article_section_is_present = FALSE) OR article_tag_is_present = FALSE)
    • Severity: STANDARD
    • Diagnostic Message: "Article category metadata (section/tag) is missing."
  • Trigger Rule 127: twitter:site missing

    • Target Field: twitter_site
    • Evaluation Logic: twitter_site IS NULL OR btrim(twitter_site) = '' OR twitter_site_is_present = FALSE
    • Severity: STANDARD
    • Diagnostic Message: "Twitter site handle metadata is missing."
  • Trigger Rule 128: twitter:creator missing on article-like pages

    • Target Field: twitter_creator
    • Evaluation Logic: is_article_like_page = TRUE AND (twitter_creator IS NULL OR btrim(twitter_creator) = '' OR twitter_creator_is_present = FALSE)
    • Severity: STANDARD
    • Diagnostic Message: "Twitter creator handle metadata is missing for article-like content."
  • Trigger Rule 129: twitter:image:alt missing

    • Target Field: twitter_image_alt
    • Evaluation Logic: og_image IS NOT NULL AND (twitter_image_alt IS NULL OR btrim(twitter_image_alt) = '' OR twitter_image_alt_is_present = FALSE)
    • Severity: IMPORTANT
    • Diagnostic Message: "Twitter image alt metadata is missing."
  • Trigger Rule OG core consistency: og:type, og:title, og:description, og:url, og:image

    • Target Field: og_type
    • Evaluation Logic: og_type IS NULL OR btrim(og_type) = '' OR og_title IS NULL OR btrim(og_title) = '' OR og_description IS NULL OR btrim(og_description) = '' OR og_url IS NULL OR btrim(og_url) = '' OR og_url_is_valid = FALSE OR og_image IS NULL OR btrim(og_image) = '' OR og_image_is_valid = FALSE
    • Severity: IMPORTANT
    • Diagnostic Message: "Core Open Graph metadata is incomplete, empty, or invalid."
  • Trigger Rule Final: Social & Open Graph issue state

    • Target Field: social_og_bundle_issue_detected
    • Evaluation Logic: social_og_bundle_issue_detected = TRUE
    • Severity: CRITICAL
    • Diagnostic Message: "Computed summary flag becomes true when any of the 13 Social & Open Graph checklist items is triggered."

Sources

Long description

Open Graph is a metadata protocol used by social platforms to understand what title, description, image, URL, and contextual metadata should be shown when a page is shared. This document treats Issue 97 as the master bundle that groups all 13 Social & Open Graph checklist checks together: 97, 99, and 119-129.

When social metadata is implemented correctly, link previews usually show a meaningful title (og:title), a concise summary (og:description), a stable public URL (og:url), a visual preview image (og:image), an expected content type (og:type), image dimensions (og:image:width, og:image:height), locale (og:locale), and attribution metadata for article and Twitter contexts.

This bundle includes these 13 required checks under one issue umbrella:

  • 97: Open Graph tags baseline
  • 99: Twitter Card tags baseline
  • 119: og:image:width + og:image:height
  • 120: og:locale
  • 121: og:site_name
  • 122: og:image:alt
  • 123: article:published_time
  • 124: article:modified_time
  • 125: article:author
  • 126: article:section + article:tag
  • 127: twitter:site
  • 128: twitter:creator
  • 129: twitter:image:alt

Common failure scenarios checked by the crawler:

  • No OG tags: Shared link may show random text/image or no image at all.
  • No Twitter tags: X/Twitter cards may be incomplete or fallback to unpredictable snippets.
  • Image tag exists but no dimensions: Platforms may render inconsistent preview crops.
  • Locale/site/alt missing: Card context and accessibility quality are reduced.
  • Article page without author metadata: Reduced editorial trust and weaker attribution in social/AI surfaces.
  • Duplicate OG keys with conflicting values: Platform may choose unexpected value; preview changes unpredictably.

How to Fix

  1. Add core OG tags in the server-rendered <head> for every indexable page template.
  2. Ensure core OG keys are present and non-empty (og:title, og:description, og:type, og:url, og:image).
  3. Add og:image:width and og:image:height with valid positive integer values.
  4. Add supporting OG context tags: og:locale, og:site_name, og:image:alt.
  5. Add Twitter layer tags: twitter:site, twitter:creator (for article-like pages), twitter:image:alt.
  6. On article-like pages, add article metadata: article:published_time, article:modified_time, article:author, article:section, article:tag.
  7. Use absolute HTTPS URLs for og:url and og:image.
  8. Remove duplicate/conflicting OG/article/twitter keys from head output.
  9. Re-scrape the page in Meta Sharing Debugger or LinkedIn Post Inspector.
  10. Re-run XeoPix crawler and confirm issue flags 97, 99, and 119-129 are passing.