ScreenshotNeo

BlogHow-to

How to Add Open Graph Tags to a WordPress Website in India Without a Plugin

Add page-specific Open Graph tags to WordPress with a small PHP callback. Learn where to put the code, handle missing images, avoid duplicates, and verify the output.

By the ScreenshotNeo team4 October 20268 min read

You can add Open Graph tags to WordPress without a plugin by registering a PHP callback on the wp_head action. The callback can read the current post’s title, permalink, excerpt, and featured image, then print those values in the document head. The implementation is the same for an India-based site as for any other site; choose a locale that matches the language and region of the content.

Before adding code, inspect a post’s rendered source for existing og: tags. A theme, SEO plugin, or custom code may already emit them. Duplicate tags can lead to inconsistent previews.

1. Choose where the code will live

Use a child theme’s functions.php file or a small site-specific code component that you control. A child theme keeps this customization separate from the parent theme, whose files may be replaced during an update. Do not paste PHP into the Customizer’s Additional CSS field; that field accepts CSS.

Keep a backup or use version control, and make the change in a staging environment if your site has one. A PHP syntax error can prevent WordPress from rendering pages.

2. Add dynamic tags with the wp_head hook

The wp_head() function fires the wp_head action inside the document head, where metadata belongs. WordPress documents the hook in its wp_head() reference and Theme Handbook.

Add this callback to your child theme’s functions.php. Replace the fallback image URL with a real, publicly accessible image on your own site before publishing.

function site_output_open_graph_tags() {
    if ( ! is_singular() ) {
        return;
    }

    $post_id = get_queried_object_id();
    if ( ! $post_id ) {
        return;
    }

    $title   = get_the_title( $post_id );
    $url     = get_permalink( $post_id );
    $excerpt = get_the_excerpt( $post_id );
    $image   = get_the_post_thumbnail_url( $post_id, 'full' );

    // Replace this with a real image URL that social crawlers can fetch.
    if ( ! $image ) {
        $image = 'https://example.in/path/to/default-share-image.jpg';
    }

    if ( ! $excerpt ) {
        $excerpt = get_bloginfo( 'description' );
    }
    ?>
    <meta property="og:title" content="<?php echo esc_attr( $title ); ?>">
    <meta property="og:type" content="website">
    <meta property="og:url" content="<?php echo esc_attr( $url ); ?>">
    <meta property="og:image" content="<?php echo esc_attr( $image ); ?>">
    <meta property="og:image:alt" content="<?php echo esc_attr( $title ); ?>">
    <meta property="og:description" content="<?php echo esc_attr( wp_strip_all_tags( $excerpt ) ); ?>">
    <meta property="og:site_name" content="<?php echo esc_attr( get_bloginfo( 'name' ) ); ?>">
    <?php
}
add_action( 'wp_head', 'site_output_open_graph_tags', 5 );

The is_singular() check limits this example to individual posts and pages. The queried object ID keeps the values tied to the page being rendered. The featured-image function returns a URL or false when no image is available, so the fallback prevents an empty og:image value. See the WordPress references for featured image URLs and excerpt retrieval.

Every dynamic value printed in an HTML attribute uses esc_attr(), which is intended for escaping attribute values. The excerpt is also stripped of HTML before it is escaped. Review generated source if your theme or filters substantially alter excerpt content.

3. Set accurate metadata for your content

The Open Graph protocol requires og:title, og:type, og:image, and og:url. It recommends properties such as og:description, og:locale, and og:site_name. When you specify an image, include og:image:alt describing it. The protocol also allows repeated properties and says the first value is preferred when values conflict. Consult the Open Graph protocol for the property definitions.

Property What to use Implementation note
og:title The page’s title Use the current post or page title.
og:type The correct object type website is a general value in the example. For article content, use an accurate type such as article.
og:url The intended canonical URL Confirm permalink settings and canonical behavior on your site.
og:image A real share image URL Use the featured image or a public fallback; avoid login-protected or blocked images.
og:image:alt A concise image description Describe the image, rather than repeating unrelated page copy.
og:description A page summary Use a deliberate fallback if excerpts can be empty.
og:site_name The site name Usually the WordPress site title.
og:locale The content’s language and region The protocol format is language_TERRITORY, with en_US as its default. Choose a value matching the content; do not assume every Indian site uses the same locale.

To emit a locale, add a line inside the PHP output block, using the value that actually fits the page, for example:

<meta property="og:locale" content="en_IN">

That example is appropriate only when the content is English for an India audience. For Hindi or another language, select the corresponding language and territory instead. The India context does not require a special WordPress code path.

Choosing static or dynamic values

Static tags can suit a genuinely single-page site, but they will repeat the same values if copied across a multi-page site. A hook-based callback uses the current post’s data and lets you define behavior for missing excerpts and featured images. Its main maintenance requirement is checking that another part of the site is not already generating the same metadata.

4. Check for duplicate tags and verify the result

  1. Before changing code, open the rendered source of a representative post and the home page. Search for og: and note which theme, plugin, or custom component supplies the tags.
  2. If you are replacing existing output, remove or disable that output path, or adjust your callback so the page emits one coherent set. WordPress’s Open Graph plugin listing is one example of a plugin that can add these tags.
  3. Save the callback and load a post and a page. Use the browser’s view-source feature and confirm the tags are in the document head and have the intended values.
  4. Check that the image URL is publicly fetchable without a login or hotlink restriction. Test a page with a featured image and one without it.
  5. Confirm the page still renders and check your PHP error log for fatal errors.
  6. If a sharing platform shows an old preview, use that platform’s current official preview refresh tool if available. It may have cached previous metadata.

For each representative page, confirm there is one intended value for og:title, og:type, og:url, and og:image; the URL is the intended canonical address; and the fallback image and description behave as planned. The protocol’s first-tag preference makes duplicate values especially worth resolving.

5. Troubleshooting

Symptom Likely cause Fix
No Open Graph tags in source The callback is not loaded, the action is not reached, or the page is not singular. Check the child theme is active, confirm the code is in PHP outside another function, and inspect a post or page that passes is_singular().
Tags appear twice or previews show the wrong title The theme, an SEO plugin, or another callback also emits tags. Inspect source for every og: property and remove or configure the duplicate output path.
Image property is empty or the preview has no image No featured image exists, the fallback is still a placeholder, or the image cannot be fetched publicly. Set a real fallback URL, verify it loads without authentication, and check the rendered og:image value.
Excerpt is blank or unsuitable The post has no usable excerpt, or a filter changes excerpt output. Set a deliberate fallback, such as the site description, or implement an editorial summary field. Inspect the final attribute in source.
Special characters break the markup Dynamic content was printed without attribute escaping. Use esc_attr() for each value printed into a content attribute.
PHP error or blank page after saving A syntax error or misplaced PHP tag was introduced. Restore the backup or revert the change, review the PHP error log, and correct the syntax before re-enabling it.
Source is correct but the share preview is old The platform may retain a cached preview. Use the platform’s current official refresh or inspection option if available, then check again later.

6. Performance, reliability, and maintenance

This callback reads post data and prints a small set of tags during normal page rendering; it does not require a browser service or an external API call. Keep the callback focused, avoid expensive custom lookups, and guard it so it runs only on the page types you intend to describe.

Reliability depends on correct values and accessible assets: use a valid permalink, provide a real image fallback, escape attribute output, and check pages where excerpts or thumbnails are absent. After changing themes or SEO settings, inspect source again because metadata output may change. There is no India-specific hosting or crawler requirement established by the cited WordPress and Open Graph documentation.

Or skip the browser setup

If you are also building a workflow that needs rendered page screenshots while reviewing or sharing pages, ScreenshotNeo is a website screenshot API and MCP server. It is separate from Open Graph generation: it captures a rendered page as an image or PDF, while the PHP callback above adds metadata to your WordPress HTML.

One GET request captures a page. See the ScreenshotNeo API documentation for options and configuration.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.in -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://example.in"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://example.in'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', image));
  • Cookie and consent banners, newsletter popups, and chat widgets are removed before the shot; each cleanup step can be turned off.
  • Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing; response headers identify the page verdict and billing status.
  • An MCP server lets AI agents, including Claude and Cursor, take screenshots with tools such as take_screenshot, get_page_info, and capture_pdf.
  • The free plan includes 1,000 screenshots a month with no card. Paid plans start at $5 for 3,000 screenshots.

Create a free ScreenshotNeo account and get 1,000 screenshots a month with no card.

FAQ

Do Open Graph tags change how a WordPress page looks in a browser?

No. They are metadata in the document head used by systems that interpret Open Graph properties.

Do I need a plugin just to create social sharing metadata?

No. WordPress’s head hook can print the tags directly. A plugin may already be doing so, which is why checking for existing output is an important first step.

Should every page use og:type set to website?

No. Use the type that accurately describes the object. The sample uses website as a general starting value; article pages can use an article type.

Is this implementation specific to India?

No. The PHP pattern is general. Set locale and page content according to the language and region each page actually targets.

Sources