=== PlugUpp Dynamic OG Image Generator ===
Contributors: plugupp
Tags: og image, open graph, social sharing, screenshot, seo
Requires at least: 6.0
Tested up to: 7.1
Stable tag: 2.7.1
Requires PHP: 7.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Automatically generates real screenshot-based Open Graph images for your pages and posts - no templates, just your actual page.

== Description ==

Most SEO plugins let you set a static image as your og:image. PlugUpp Dynamic OG Image Generator goes further: it takes a real browser screenshot of each page and uses that as the og:image. When someone shares your link, social platforms see exactly what your page looks like.

Captures run in the background via WP-Cron. The plugin submits each job to the PlugUpp screenshot service, which renders at the 1200x630 Open Graph size and delivers the result back to your site. The cached image is injected as og:image, overriding your SEO plugin's output wherever a screenshot is available.

You can also pick Featured image, Featured image with a screenshot fallback, or a Custom image from your Media Library, per content type and per individual post. Auto-screenshot is the standard choice; pick something else when you would rather use an image you already have.

And it is not just posts and pages: the Site-wide Pages section covers the pages that have no post at all - your homepage, archive pages, category and tag pages, and author pages. These pages have no featured image by definition, so a screenshot is often the only real image they can carry. Homepage coverage is free; archive, taxonomy and author pages come with Premium.

> **Upgrade to Premium** for custom post type and WooCommerce coverage, per-page capture overrides, country routing, retina captures, Media Library integration, and higher monthly screenshot quotas. One licence covers a single site up to unlimited sites. [See plans and pricing](https://plugupp.com/plugins/dynamic-og-image-generator/#pricing)

= What you get on the free plan =

* **Real-screenshot og:image** - actual browser captures at the standard 1200x630 Open Graph size, not templates and not featured-image fallbacks
* **Per-post Image Source picker** - choose Auto-screenshot, Featured image, Featured image with screenshot fallback, Custom image, or Off, from the block editor sidebar on each post
* **Per-content-type Source defaults** - set the default behaviour for Posts and Pages independently from the Settings page
* **Homepage og:image** - your front page gets a real screenshot og:image too, something most SEO plugins have struggled with for years
* **SEO plugin aware** - works alongside Yoast SEO, Rank Math, and All in One SEO. The plugin replaces only the og:image and twitter:image tags; titles, descriptions, structured data, and sitemaps stay with your SEO plugin
* **Page-builder content detection** - edits made in Elementor, Beaver Builder, Divi, BeTheme, Oxygen, Themify, and Breakdance trigger the same auto-regen as a Block Editor save
* **Bulk actions** - set the Image Source for any selection of posts from the standard Posts and Pages list screens, including alongside any list filter (category, tag, Page Generator Pro, and similar)
* **Automatic refresh schedule** - cached screenshots refresh on a configurable interval (30 days by default), with a background sweep that cleans up cached images you no longer need after a 14-day grace
* **Cache management** - view cache size, clear all screenshots, or queue a full regeneration from the Dashboard
* **Quota awareness** - clear in-admin counters and status messages when your monthly allowance is approaching or has reached its cap

= What Premium adds =

* **Site-wide coverage** - screenshot og:images for archive pages, category and tag pages, and author pages, with a live page count shown before you enable each group and a per-group custom image option
* **Custom post types and WooCommerce products** - extend Image Source defaults and auto-screenshot capture to any public CPT, including WooCommerce products
* **Per-page capture overrides** - viewport width, capture delay, hide selectors, scroll-into-view, click-before-capture, dark mode, and country routing on individual posts from the block editor sidebar
* **Custom capture URL** - point a post's screenshot at a different https URL, even on another domain. Ideal for portfolio or case-study posts where the page worth showing is the client site itself
* **Country routing** - capture each page as it renders from a chosen region for IP-localised content
* **Retina captures** - 2x or 3x device scale factor for sharper share previews
* **Media Library integration** - save each capture as a Media Library attachment, optionally set it as the post's Featured Image, and delete the previous capture on regenerate
* **Higher monthly screenshot allowance** - for larger or busier sites
* **Multi-site licensing** - one licence covers 1, 3, 5, or unlimited sites (Personal, Pro, Business, Agency)
* **Email support**

[See the full plan comparison and pricing](https://plugupp.com/plugins/dynamic-og-image-generator/#pricing).

== External services ==

This plugin connects to two external services. Both are operated by PlugUpp.

= PlugUpp Screenshot Service =

The plugin sends screenshot job requests to the PlugUpp Screenshot Service at https://screenshots.plugupp.com, which captures browser screenshots of your pages and returns them for use as Open Graph images.

* When data is sent: when a page or post is first published, when an enabled page is updated and the "Regenerate on post update" setting is on, when you click "Regenerate Now" in the block editor, on the configurable refresh schedule (default 30 days), and when the Settings page is loaded (to populate the connection status indicator and the screenshot usage figures).
* What data is sent: the public URL of the page to be captured, your PlugUpp licence key, your site's Freemius site identifier, the URL the service should send the result to (a REST endpoint on your site), and the capture configuration (viewport width, image quality, country routing, etc.).
* What is received back: the captured screenshot image, which is downloaded by your site and stored locally as a WebP file in your uploads directory.
* Terms of service: https://plugupp.com/terms-of-service/
* Privacy policy: https://plugupp.com/privacy-policy/
* Legal notice: https://plugupp.com/legal-notice/

= Freemius =

The plugin uses the Freemius platform for licence activation, plan changes, plugin updates (for paid plans), and as the Merchant of Record for purchases.

* When data is sent: on first plugin activation as part of the user-consented opt-in flow, on licence activation or deactivation, on plugin update checks (paid plans), and on uninstall (for optional feedback). Sending the initial opt-in data is the user's choice - declining the opt-in still lets the plugin work, but skips telemetry.
* What data is sent: standard Freemius opt-in data including site URL, administrator email address, WordPress version, PHP version, plugin version, and active theme name.
* Terms of service: https://freemius.com/terms/
* Privacy policy: https://freemius.com/privacy/

== Installation ==

1. Install from the WordPress.org plugin directory (Plugins > Add New), or upload the plugin ZIP (Plugins > Add New > Upload).
2. Activate the plugin.
3. Open OG Images > Settings and pick an Image Source default for Posts and Pages. Auto-screenshot is the standard choice; pick a different mode when you have featured images you would rather use as the og:image.
4. Screenshots begin generating in the background as WP-Cron fires.

No API key or additional account is required. The plugin authenticates with the PlugUpp screenshot service automatically using your licence.

== Frequently Asked Questions ==

= Do I need to set up anything beyond a PlugUpp licence? =

No. The plugin connects to the PlugUpp screenshot service using your licence. No separate API key or additional signup is needed.

= How long does it take for a screenshot to appear? =

Screenshots are generated asynchronously. The plugin submits a job and the result is delivered back to your site - typically within a few seconds to a couple of minutes depending on server load. On a site with active traffic and WP-Cron firing regularly, screenshots usually appear shortly after publishing. You can also trigger an immediate regeneration from the block editor sidebar using the Regenerate Now button.

= What happens while a screenshot is being generated? =

Depending on your Image Source setting, either your SEO plugin's default og:image is shown, your Featured image, a Custom image you chose, or no og:image until the screenshot is ready.

= Can I use a different image on specific pages? =

Yes. Open any page or post in the block editor and find the OG Image panel in the sidebar. Pick Auto-screenshot, Featured image, Featured image with screenshot fallback, Custom image, or Off for that specific post - this overrides the content-type default.

= Does it work with page builders like Elementor, Divi, or BeTheme? =

Yes. The plugin detects content changes from the Block Editor and Classic Editor (always), and from the following page builders that store their content separately from the main post body: Elementor, Beaver Builder, Divi (Elegant Themes), BeTheme (Muffin Builder), Oxygen, Themify Builder, Breakdance. If you use a builder not listed here, you can still trigger captures manually with the Regenerate Now button in the block editor sidebar - or let us know which builder you would like added.

= What happens if my screenshot quota is exhausted? =

Posts that would have been screenshotted are marked with a "quota reached" status. No screenshot is attempted until the next billing period when quota resets. You can upgrade your plan at any time to increase your quota - see https://plugupp.com/plugins/dynamic-og-image-generator/#pricing.

= What do I get with Premium? =

Premium raises your monthly screenshot quota and unlocks per-page capture overrides (viewport width, capture delay, hide selectors, scroll-into-view, click-before-capture, dark mode, country routing, and retina), Media Library integration, and Image Source coverage for custom post types including WooCommerce products. The full plan comparison and current pricing are at https://plugupp.com/plugins/dynamic-og-image-generator/#pricing.

= Does it work with WooCommerce product pages? =

Yes, on Premium. Custom post type coverage extends the Image Source defaults and auto-screenshot pipeline to WooCommerce products and any other public CPT. The free plan covers Posts and Pages.

= Does this replace my SEO plugin? =

No. It only handles og:image. Your SEO plugin continues to manage all other meta tags. When a screenshot is ready (or your Featured image or Custom image is the chosen source), the plugin overrides only the og:image and twitter:image tags.

== Screenshots ==

1. Dashboard - recent screenshot activity with image previews, including site-wide pages such as your homepage, plus pending and failed captures with reasons.
2. Settings - Image Source per content type, the Site-wide Pages section for homepage and archive coverage, capture defaults, scheduled refresh.
3. Cache management - inspect cache size and clear all cached screenshots.
4. Block editor sidebar - pick the image source per post (Auto-screenshot, Featured image, Custom image, etc.), preview what will emit, regenerate on demand.
5. Example og:image on social media - a real page screenshot used as the share preview.

== Changelog ==

= 2.7.1 =
* New: a `doig_should_capture` developer filter. Return false to exclude any post from screenshot capture in code - handy for skipping programmatically generated pages on large sites. See the capacity planning guide in the docs.
* Improved: dismissing a site-wide notice (like the missing favicon nudge) now dismisses it across all PlugUpp plugin dashboards, not just this one.
* Fixed: a rare case where queued submission retries could wait up to twelve minutes longer than intended.
* Confirmed compatible with WordPress 7.1.

= 2.7.0 =
* New: site-wide coverage. Your homepage, archive pages, category and tag pages, and author pages can now have real screenshot OG images too - pages that have no featured image by definition, so template-based approaches have nothing to show there. Configure them in the new Site-wide Pages section under Settings. Homepage coverage is free; archive, taxonomy and author pages are Premium.
* New: each site-wide page can use a screenshot, a custom image, or stay off - and enabled pages join the scheduled refresh, Regenerate All and the Dashboard tables like any post.
* Improved: the Settings section shows a live page count next to each taxonomy before you enable it, so you can see the screenshot cost of a toggle up front.

= 2.6.2 =
* Improved: failed screenshots now explain themselves. The editor sidebar and the Dashboard Failed table show what went wrong in plain language, with a short what-to-do hint and a direct link to the matching troubleshooting guide for the common causes.
* Improved: the Dashboard now tells you up front when screenshots have failed, when captures are completing via the slower polling fallback (a sign your host may be blocking the plugin's callback), and when the capture queue is waiting on a stalled WP-Cron.
* Fixed: the licence-expired notice showed a raw data snippet instead of the plain message.

= 2.6.1 =
* Improved: Regenerate All and the daily refresh now work through large sites much faster on standard shared hosting. The queue keeps itself moving in the background instead of waiting for WP-Cron between batches, which stays in place as a safety net.
* Improved: a brand-new post's first screenshot is now captured right away on quiet sites, instead of waiting for the next visitor to trigger WP-Cron.

= 2.6.0 =
* New (Premium): custom capture URL per post. Point a post's screenshot at a different https URL - including one on another domain - from the Capture Overrides panel in the block editor. Ideal for portfolio or case-study posts where the page worth showing is the client site itself. Cross-domain capture requires an active paid licence.
* New: Clear cached screenshot button in the block editor sidebar. Deletes the cached image and resets the status without queueing a fresh capture, so no quota is used - the scheduled refresh or your next content update re-captures when you are ready.
* New: favicon check. Once a week the plugin checks whether your site serves a favicon and shows a dismissible note on the Dashboard if not - chat platforms such as Slack, Discord and WhatsApp show a broken globe icon next to the link preview without one. Informational only; captures are never blocked or delayed.

= 2.5.3 =
* New: image previews in the Dashboard's Recent screenshot activity table. Click a thumbnail to open the full-size capture in a lightbox.
* New: the Recent screenshot activity table now shows the Image source for each page (Auto-screenshot, Featured image, Custom image, and so on), and the Pending table shows how many submission attempts a capture has made.
* Improved: the Dashboard tables now follow the standard WordPress list-table conventions - hover any row for the usual Edit and View actions.
* Improved: the Regenerate All Screenshots button now sits directly under the status cards instead of below the activity tables, where it was easy to miss.
* Changed: the plugin's display name is now "PlugUpp Dynamic OG Image Generator".

= 2.5.0 =
* Improved: redesigned Logs tab with a cleaner toolbar, a new "Errors and warnings" log level, and level-coloured entries.
* Changed: the log file now lives at uploads/dynamic-og-image-generator/dynamic-og-image-generator.log, and downloaded logs get a self-identifying, timestamped filename.
* Fixed: a possible error when the plugin tried to record a warning while checking your usage data.
* Improved: clearer "Custom post types" heading on the Settings page (Premium).

= 2.4.1 =
* Improved: screenshot job polling now runs on a dedicated 15-minute schedule, decoupled from bulk processing. Pending captures are checked on a predictable cadence even when no bulk work is driving WP-Cron, giving more consistent recovery on hosts where callbacks are blocked or WP-Cron fires intermittently.

= 2.4.0 =
* New: Image source picker. Pick how each page's og:image is sourced - Auto-screenshot (the previous default), Featured image, Featured image with screenshot fallback, Custom image from your Media Library, or Off - per post from the block editor sidebar, and per content type from the Settings page. Featured and Custom modes do not consume your screenshot quota.
* New: top-level OG Images menu. Settings live under OG Images > Settings instead of the previous Settings > Dynamic OG Images path. New Dashboard sub-page shows plan and quota at a glance, plus recent activity, pending captures, and failed captures with reasons.
* New: bulk Image Source actions on the Posts and Pages list screens. Five variants - Auto-screenshot, Featured image, Featured image (with screenshot when missing), Off, and Reset to default - replacing the previous Enable / Disable / Reset trio.
* New: featured-image dimensions warning in the block editor sidebar. When the chosen Featured or Custom image is below 200x200 (the floor where major social platforms start skipping thumbnails), the sidebar flags it inline. No behaviour change, just a heads-up.
* Changed: cached screenshots are automatically cleaned up when no longer used. When a post's resolved Image source is no longer Auto-screenshot or Featured-with-fallback, the cached file is kept for a 14-day grace period and then deleted by a weekly background sweep. Flip back inside the grace window and the cache is preserved with no quota burn.
* Changed: screenshot quota is only used when the resolved Image source actually needs a screenshot. The daily refresh sweep, Regenerate All, post-update auto-regen, and the block editor Regenerate Now button all skip posts in Featured / Custom / Off modes (and Featured-with-fallback posts that already have a Featured image).
* Migrated: existing installs keep their previous Enable Sitewide setting on upgrade. Posts and Pages that were Enabled before 2.4.0 map to Auto-screenshot; Disabled maps to Off. Per-post overrides are preserved.

= 2.3.0 =
* Fixed: the Dynamic OG Image sidebar widget now appears on every public custom post type in the Premium build, not only the ones ticked under Settings > Custom post types. The override surfaces (sidebar widget, REST meta, bulk actions) work the same way Posts and Pages do - the sitewide tick controls automatic processing, but the per-post override capability is always available. Customers can now opt in individual items on a CPT (e.g. one specific Product) without having to enable the whole CPT for the sweep.
* Added: a dismissible notice when Page Generator Pro is detected on the same site. PGP-generated pages draw from the monthly screenshot quota along with hand-written content, which on large catalogues can exhaust the allowance silently. The notice links to a new capacity-planning guide covering post-type exclusions, refresh intervals, and per-page overrides for high-page-count sites.

= 2.2.1 =
* Refined: small layout polish on the Custom post types row of the Settings page - each available type now sits on its own line for legibility, matching the Posts and Pages checkboxes above.

= 2.2.0 =
* Changed: the "Enable sitewide" setting is now split into separate "for Posts" and "for Pages" checkboxes. Sites usually want to treat Posts (which often have featured images already) differently from Pages (bare landing pages where the screenshot is the differentiator); the split lets you opt one in and leave the other off. Existing sites are migrated automatically - whatever your previous "Enable sitewide" setting was, both new checkboxes inherit it on first load. Both still default to off on fresh installs so a new site never starts consuming quota before you have consciously opted in.
* Added: bulk actions on the standard Posts and Pages list screens (Bulk actions dropdown). Three actions: "Enable Dynamic OG image", "Disable Dynamic OG image", and "Reset Dynamic OG to default". Select any number of rows - including the full set produced by a built-in or third-party list filter, such as a category, tag, or Page Generator Pro's filter - and apply the action across all of them in one click. Drives the same per-post override the OG Image panel in the block editor writes to, so the two stay in sync.
* Added (Premium): support for additional public custom post types. A new "Custom post types (Premium)" row in the Enable-sitewide section lists every public custom post type registered on your site (WooCommerce products appear automatically when WooCommerce is active). Tick a type to bring it into scope: the block editor sidebar, the bulk actions, the daily refresh sweep, and the Regenerate All button all extend to it immediately.

= 2.1.3 =
* Fixed: on Yoast SEO sites where the page already had its own OG image (a featured image or a Yoast-set Open Graph image), the 2.1.2 fix added a second og:image tag instead of replacing the existing one. Pages ended up with two og:image meta tags pointing at the same screenshot URL but reporting different width/height values, which is invalid Open Graph markup and confuses social-preview scrapers. The plugin now adds the screenshot to Yoast's image collection only when Yoast has no image of its own, and otherwise rewrites the existing one. Exactly one og:image tag is emitted per page in either case.
* Fixed: og:image:width / og:image:height / og:image:type tags now consistently report 1200, 630, and image/webp under Yoast (matching the actual screenshot dimensions and format). Previously, when Yoast had its own image with different dimensions, those dimensions were left in place after the URL was rewritten to ours.

= 2.1.2 =
* Fixed (critical): the og:image tag was missing entirely on sites using Yoast SEO when no other og:image was set for the page. Yoast's rewrite-only filter only modifies an existing og:image and does nothing when no image is present, so on pages with no featured image and no Yoast default the og:image tag did not ship at all. Result: Facebook, LinkedIn, Slack, WhatsApp and Discord previews showed no image even though the screenshot existed. The plugin now adds the screenshot to Yoast's internal image collection directly so the tag is guaranteed to ship. Rank Math and All in One SEO were not affected by this specific issue.
* Added: a new "Scheduled refresh" checkbox on the Settings page. When off, cached screenshots are kept indefinitely until you explicitly regenerate them (per post or via Regenerate All Screenshots). Post-update auto-regen still works when its own setting is enabled. Defaults to on, so existing installs keep their current schedule-driven behaviour.
* Changed: the setup banner shown before plugin activation now branches between two states. After you click "Allow & Continue" but before clicking the confirmation link in the email, the banner now reads "Check your email to finish setup" with a Refresh button - so you are not asked to "Activate now" again when you are already waiting on your own inbox.
* Changed: the setup banner icon is now a WordPress dashicon to match the visual style used across other PlugUpp plugins.

= 2.1.1 =
* Compliance: addressed four Plugin Check ERROR-severity findings on the 2.1.0 build. Two missing `translators:` comments on the live screenshot-usage headline strings, and two output-escape annotations on integer values in the Refresh interval helper text. The values were already integer-cast; this re-casts at the `printf` call site so the static analyser sees the safety explicitly. No customer-visible change.

= 2.1.0 =
* First public release on the WordPress.org plugin directory.
* Real screenshot-based og:image. The plugin captures a real browser screenshot of each page at the standard 1200x630 Open Graph size and uses it as the og:image. No templates, no featured-image fallbacks - the actual page is what social platforms see when your link is shared.
* No third-party API key. The plugin connects to the PlugUpp screenshot service automatically using your licence. No separate account to manage and no per-request signup.
* Per-post controls in the Gutenberg sidebar - per-page enable/disable, live status, thumbnail preview of the current capture, and a "Regenerate Now" button. Premium adds per-page overrides for viewport width, capture delay, hide selectors, scroll-into-view, click-before-capture, dark mode, country routing, and Media Library integration.
* Page-builder content-save detection. Edits made in Elementor, Beaver Builder, Divi, BeTheme (Muffin Builder), Oxygen, Themify Builder, or Breakdance trigger the same auto-regeneration as a Block Editor save. Two filters (`doig_supported_builders` and `doig_render_affecting_meta_keys`) let site owners add their own.
* Works alongside Yoast SEO, Rank Math, and All in One SEO via each plugin's own image filter hooks. Other meta tags (titles, descriptions, structured data, canonicals, sitemaps) stay under your SEO plugin's control. The plugin runs without an SEO plugin too, emitting its own og:image and twitter:image block.
* Configurable fallback image - your SEO plugin's default, a custom image from your Media Library, or none - shown while a screenshot is being generated or for posts that have not yet been captured.
* Configurable refresh schedule (default 30 days) with a background daily sweep, optional auto-regeneration on post update, and a manual "Regenerate All Screenshots" action on the Settings page (with a backup-recommendation warning before bulk operations).
* HTTPS pre-flight check with an actionable message when the WordPress Site Address is misconfigured as http://. Prevents silent capture failures that would otherwise consume quota for no result.
* Asynchronous capture pipeline. Jobs are delivered via a signed callback with a polling fallback for hosts that block inbound callbacks. On PHP-FPM hosts the callback handler uses `fastcgi_finish_request()` to return in single-digit milliseconds even under bulk-regeneration load.
* Live screenshot-usage section on the Settings page showing your current startup count, monthly count, quota-reset date, and subscription-renewal date. Figures come from the screenshot server live so they always match reality.
* Cache management on the Settings page - cached file count, total disk usage, "Clear Entire Cache", and "Regenerate All Screenshots" with the bulk-operations safety warning.
* Quota awareness. Posts that would exceed the monthly cap are marked with a `quota_exceeded` status and re-queued automatically when the quota resets at the start of your next billing period. Existing screenshots continue to be served in the meantime.
* Documentation links throughout the plugin UI. The Plugins admin row, the Settings tab, and the Logs tab all link out to context-relevant pages on the public documentation site at https://docs.plugupp.com/dynamic-og-image-generator/.
