{"id":315673,"date":"2026-05-24T10:56:19","date_gmt":"2026-05-24T10:56:19","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/send-static-to-pages\/"},"modified":"2026-05-24T10:55:43","modified_gmt":"2026-05-24T10:55:43","slug":"staticforge-for-cloudflare-pages","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/staticforge-for-cloudflare-pages\/","author":23298972,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.1.0","stable_tag":"1.1.0","tested":"7.0","requires":"5.8","requires_php":"7.4","requires_plugins":null,"header_name":"StaticForge for Cloudflare Pages","header_author":"Gunjan Jaswal","header_description":"Auto-export the entire WordPress site (posts, pages, custom post types, archives, SEO meta) as static HTML with inlined CSS, and deploy to Cloudflare Pages on every publish\/update via the Direct Upload API.","assets_banners_color":"7d6b7f","last_updated":"2026-05-24 10:55:43","external_support_url":"","external_repository_url":"","donate_link":"https:\/\/ko-fi.com\/gunjanjaswal","header_plugin_uri":"https:\/\/github.com\/gunjanjaswal\/staticforge-for-cloudflare-pages","header_author_uri":"https:\/\/www.gunjanjaswal.me","rating":0,"author_block_rating":0,"active_installs":0,"downloads":24,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.1.0":{"tag":"1.1.0","author":"gunjanjaswal","date":"2026-05-24 10:55:43"}},"upgrade_notice":{"1.1.0":"<p>Renamed from &quot;Send Static to Pages&quot;. Settings\/logs\/cron auto-migrate. WP 7.0 tested. Adds <strong>Bundle <code>\/wp-content\/uploads\/<\/code> into deploy<\/strong> for shared-hosting origins blocked by CF proxies, and fixes <code>*.pages.dev<\/code> redirect (now JS-based \u2014 old <code>_middleware.js<\/code> never ran under Direct Upload).<\/p>","1.0.1":"<p>Recommended update. Adds standalone Person + ProfilePage schema on author pages, fallback sitemap generation, granular sitemap settings, dashboard auto-noindex, featured-image LCP boost, escaped-slash URL rewriting for JSON-LD, and an important fatal-error fix from a malformed line comment in 1.0.0.<\/p>","1.0.0":"<p>First public release.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3546099,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3546100,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500-es.png":{"filename":"banner-1544x500-es.png","revision":3546095,"resolution":"1544x500","location":"assets","locale":"es","width":1544,"height":500},"banner-1544x500-es_ES.png":{"filename":"banner-1544x500-es_ES.png","revision":3546096,"resolution":"1544x500","location":"assets","locale":"es_ES","width":1544,"height":500},"banner-1544x500-rtl.png":{"filename":"banner-1544x500-rtl.png","revision":3546098,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3546094,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250-es.png":{"filename":"banner-772x250-es.png","revision":3546104,"resolution":"772x250","location":"assets","locale":"es","width":772,"height":250},"banner-772x250-es_ES.png":{"filename":"banner-772x250-es_ES.png","revision":3546107,"resolution":"772x250","location":"assets","locale":"es_ES","width":772,"height":250},"banner-772x250-rtl.png":{"filename":"banner-772x250-rtl.png","revision":3546093,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3546101,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.1.0"],"block_files":[],"assets_screenshots":[],"screenshots":{"1":"Settings page with all configuration fields, SEO injection toggles, and live activity log.","2":"Built-in Setup Guide with colour-coded step-by-step walk-through.","3":"Activity log with status pill, render progress, batch-by-batch upload telemetry.","4":"Sample JSON-LD output: Article with linked author Person + Organization publisher.","5":"Sample author archive: Person + ProfilePage schema with sameAs social links."}},"plugin_section":[],"plugin_tags":[3882,19981,186,1557,250566],"plugin_category":[55],"plugin_contributors":[245263],"plugin_business_model":[],"class_list":["post-315673","plugin","type-plugin","status-publish","hentry","plugin_tags-cloudflare","plugin_tags-deploy","plugin_tags-seo","plugin_tags-sitemap","plugin_tags-static-site","plugin_category-seo-and-marketing","plugin_contributors-gunjanjaswal","plugin_committers-gunjanjaswal"],"banners":{"banner":"https:\/\/ps.w.org\/staticforge-for-cloudflare-pages\/assets\/banner-772x250.png?rev=3546101","banner_2x":"https:\/\/ps.w.org\/staticforge-for-cloudflare-pages\/assets\/banner-1544x500.png?rev=3546094","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/staticforge-for-cloudflare-pages\/assets\/icon-128x128.png?rev=3546099","icon_2x":"https:\/\/ps.w.org\/staticforge-for-cloudflare-pages\/assets\/icon-256x256.png?rev=3546100","generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p><strong>StaticForge for Cloudflare Pages<\/strong> turns your WordPress site into a static site that lives on Cloudflare Pages, automatically. On every publish or update of any selected post type, the plugin renders your whole site to static HTML, injects a complete SEO metadata baseline (when no other SEO plugin is present), inlines all linked CSS so pages are self-contained, mirrors your sitemap structure, ships an editable <code>robots.txt<\/code>, and pushes everything to Cloudflare Pages via the Direct Upload API.<\/p>\n\n<p>The WordPress install (your \"dashboard\") becomes the editor only. Public visitors hit the static deployment on Cloudflare's edge \u2014 fast, free, and resilient.<\/p>\n\n<h4>Key features<\/h4>\n\n<ul>\n<li><strong>Whole-site export<\/strong> \u2014 homepage, posts, pages, custom post types, taxonomy archives, author archives.<\/li>\n<li><strong>Theme-independent<\/strong> \u2014 works with any theme. Renders pages exactly as a real visitor would see them.<\/li>\n<li><strong>Inlined CSS<\/strong> \u2014 all <code>&lt;link rel=\"stylesheet\"&gt;<\/code> tags are fetched and embedded as <code>&lt;style&gt;<\/code> blocks. Each deployed page is fully self-contained.<\/li>\n<li><strong>Featured image LCP boost<\/strong> \u2014 auto-adds <code>fetchpriority=\"high\"<\/code>, <code>loading=\"eager\"<\/code>, <code>decoding=\"async\"<\/code> to the post's featured image so the browser prioritises it as the LCP candidate. Improves Core Web Vitals on every theme that uses <code>the_post_thumbnail()<\/code> or <code>get_the_post_thumbnail()<\/code>.<\/li>\n<li><strong>Built-in SEO metadata injection<\/strong> \u2014 when no other SEO plugin is detected, automatically emits a full baseline:\n\n<ul>\n<li><code>&lt;meta description&gt;<\/code> \u2014 smart fallback chain (excerpt \u2192 trimmed content \u2192 user bio \u2192 term description \u2192 site tagline).<\/li>\n<li><code>&lt;meta robots&gt;<\/code> with <code>index, follow, max-image-preview:large<\/code> and friends.<\/li>\n<li><code>&lt;link rel=\"canonical\"&gt;<\/code>.<\/li>\n<li><strong>Open Graph<\/strong>: <code>og:type<\/code>, <code>og:title<\/code>, <code>og:description<\/code>, <code>og:url<\/code>, <code>og:site_name<\/code>, <code>og:locale<\/code>, <code>og:image<\/code> with dimensions and alt; <code>article:published_time<\/code>, <code>article:modified_time<\/code>, <code>article:author<\/code>, <code>article:section<\/code>, <code>article:tag<\/code> on posts; <code>profile:first_name<\/code>, <code>profile:last_name<\/code>, <code>profile:username<\/code> on author pages.<\/li>\n<li><strong>Twitter Card<\/strong> \u2014 <code>summary_large_image<\/code> when an image is available, otherwise <code>summary<\/code>; title, description, image, creator.<\/li>\n<\/ul><\/li>\n<li><strong>Rich JSON-LD schemas<\/strong> \u2014 auto-emitted in <code>&lt;head&gt;<\/code>:\n\n<ul>\n<li><code>WebSite<\/code> + <code>SearchAction<\/code>, <code>Organization<\/code> on every page.<\/li>\n<li><code>Article<\/code> with linked <code>author<\/code> Person, <code>publisher<\/code> Organization, image, dates, articleSection, keywords on single posts.<\/li>\n<li><code>WebPage<\/code> with <code>primaryImageOfPage<\/code> on pages and custom post types.<\/li>\n<li><strong><code>Person<\/code> + <code>ProfilePage<\/code> schema on author archives<\/strong> \u2014 display name, URL, bio, avatar <code>ImageObject<\/code> (256\u00d7256), <code>sameAs<\/code> social links pulled from <code>user_url<\/code> and Twitter\/Facebook\/LinkedIn\/Instagram\/YouTube\/GitHub user meta.<\/li>\n<li><code>CollectionPage<\/code> for taxonomy and term archives.<\/li>\n<li><code>BreadcrumbList<\/code> on all singulars and archives.<\/li>\n<li><strong>Auto-detected <code>FAQPage<\/code><\/strong> \u2014 extracts Q\/A pairs from Yoast \/ Rank Math \/ SEOPress FAQ blocks, OR native HTML5 <code>&lt;details&gt;&lt;summary&gt;<\/code> markup.<\/li>\n<li><strong>Auto-detected <code>HowTo<\/code><\/strong> \u2014 extracts steps from Yoast \/ Rank Math HowTo blocks, OR posts whose title starts with \"How to\" + has an ordered list with 3+ items.<\/li>\n<\/ul><\/li>\n<li><strong>Two-tier dedup safety<\/strong> \u2014 auto-disables to avoid duplicates:\n\n<ul>\n<li><strong>General SEO plugins<\/strong> (skip ALL our injection): Yoast, Rank Math, All in One SEO Pack (v4+ &amp; legacy), SEOPress, The SEO Framework, Slim SEO, Squirrly, SmartCrawl, WP Meta SEO.<\/li>\n<li><strong>Schema-only plugins<\/strong> (skip ONLY our JSON-LD; meta + og still emit): Schema &amp; Structured Data for WP &amp; AMP (saswp by Magazine3), Schema Pro by Brainstorm Force, WPSSO Core, Schema (by Hesham), Schema App, and Magazine3 Schema variants.<\/li>\n<li>Override via setting or filters (<code>sforge_seo_competing_plugin<\/code>, <code>sforge_schema_competing_plugin<\/code>).<\/li>\n<\/ul><\/li>\n<li><strong>Sitemap mirroring + fallback generation<\/strong> \u2014 discovers <code>\/sitemap.xml<\/code>, <code>\/sitemap_index.xml<\/code>, <code>\/wp-sitemap.xml<\/code>, follows index files, fetches child sitemaps, handles CDATA-wrapped <code>&lt;loc&gt;<\/code> entries, rewrites origin URLs to your live domain (including protocol-relative <code>\/\/host<\/code> variants), and strips <code>&lt;?xml-stylesheet ... ?&gt;<\/code> directives so the dashboard host doesn't leak into browser-rendered sitemap views. Bundles them all in the deploy. <strong>When the origin exposes no sitemap<\/strong> (no SEO plugin, WP core sitemap disabled, sub-directory install with non-standard paths, etc.), the plugin builds a standards-compliant <code>&lt;urlset&gt;<\/code> <code>sitemap.xml<\/code> itself from the crawled URL list \u2014 with <code>&lt;lastmod&gt;<\/code> resolved from <code>get_post_modified_time()<\/code>, <code>&lt;changefreq&gt;weekly&lt;\/changefreq&gt;<\/code>, and <code>&lt;priority&gt;<\/code> (1.0 home \/ 0.7 elsewhere). Live site always ships a sitemap.<\/li>\n<li><strong>Granular sitemap generator settings<\/strong> \u2014 when the fallback runs, you control exactly what gets listed: per-public-post-type checkboxes, include\/exclude homepage, taxonomy archives, author archives, and an option to split the output into a <code>&lt;sitemapindex&gt;<\/code> referencing per-type sub-sitemaps (<code>sitemap-post.xml<\/code>, <code>sitemap-page.xml<\/code>, <code>sitemap-authors.xml<\/code>, <code>sitemap-taxonomy-category.xml<\/code>, etc.) for cleaner Search Console submission. Independent of Export Scope. Filter <code>sforge_sitemap_groups<\/code> to mutate the URL list.<\/li>\n<li><strong>Editable robots.txt for the live site with auto-managed Sitemap: line<\/strong> \u2014 leave blank to auto-generate, or paste your own <code>Allow:<\/code> \/ <code>Disallow:<\/code> rules. Any <code>Sitemap:<\/code> directive you type is stripped and replaced with the URL of the actually-deployed sitemap (<code>sitemap.xml<\/code> \/ <code>sitemap_index.xml<\/code> \/ <code>wp-sitemap.xml<\/code> \/ etc.) so robots.txt never points at a dead URL. Independent of the dashboard's own robots.txt.<\/li>\n<li><strong>Dashboard auto-noindex on activation (social-aware)<\/strong> \u2014 when the plugin activates it locks the WordPress install out of search engines (so editors only ever appear via the static deployment). Social\/messaging\/preview scrapers (Facebook, LinkedIn, Twitter\/X, Pinterest, WhatsApp, Slack, Discord, Telegram, Applebot, Reddit, Tumblr, Mastodon, Bluesky, iframely, Embedly) are explicitly allowed <code>\/wp-content\/uploads\/<\/code> so og:image previews and oEmbed thumbnails still resolve when a post is shared. Four enforcement layers, all bypassed when the plugin's own renderer fetches a page (detected via <code>X-SFORGE-Export<\/code> header), and additionally bypassed for social-scraper user agents and <code>\/wp-content\/uploads\/<\/code> requests:\n\n<ol>\n<li>Physical <code>robots.txt<\/code> at webroot with <code>Disallow: \/<\/code> (any existing file is backed up to <code>robots.txt.sforge-backup<\/code> and restored on deactivation).<\/li>\n<li><code>robots_txt<\/code> WordPress filter for the dynamic fallback.<\/li>\n<li><code>wp_robots<\/code> filter adding <code>noindex,nofollow<\/code> to the meta robots tag.<\/li>\n<li><code>send_headers<\/code> action emitting <code>X-Robots-Tag: noindex, nofollow, noarchive, nosnippet<\/code> HTTP header on every response.\nToggle via the <strong>Block dashboard from search engines<\/strong> setting (default on); flipping the toggle applies\/restores the physical robots.txt instantly.<\/li>\n<\/ol><\/li>\n<li><strong>Defensive noindex stripping<\/strong> \u2014 removes <code>noindex<\/code> \/ <code>nofollow<\/code> \/ <code>noarchive<\/code> directives from rendered HTML before deploy, so your live site stays indexable even if the source dashboard is locked down.<\/li>\n<li><strong>Auto-deploy on publish\/update<\/strong> \u2014 debounced (default 120s) so rapid edit clusters collapse into one deploy.<\/li>\n<li><strong>Cloudflare Pages Direct Upload<\/strong> \u2014 no Git integration required. Uses the official content-addressable upload API: only changed assets are re-uploaded across deploys.<\/li>\n<li><strong>Live progress UI<\/strong> \u2014 activity log auto-refreshes every 4 seconds with batch-by-batch upload progress, render percentages, and a status pill (Idle \/ Queued \/ Working).<\/li>\n<li><strong>Setup Guide built in<\/strong> \u2014 full walk-through for Cloudflare Pages project creation, API token setup, and plugin configuration, all inside WP admin.<\/li>\n<\/ul>\n\n<h4>How it works<\/h4>\n\n<ol>\n<li>On publish\/update, plugin queues a full-site rebuild via <code>wp_schedule_single_event<\/code>.<\/li>\n<li>Crawler builds URL list (homepage + all published posts\/pages of selected types + taxonomy term archives + author archives).<\/li>\n<li>SEO injector hooks into <code>wp_head<\/code> and emits meta + JSON-LD for the rendering page (skipped if another SEO plugin is active).<\/li>\n<li>Renderer fetches each URL via <code>wp_remote_get<\/code>, inlines CSS, rewrites origin URLs to your live domain, strips defensive noindex meta and admin-bar artefacts.<\/li>\n<li>SEO module discovers and mirrors <code>\/sitemap.xml<\/code>, <code>\/sitemap_index.xml<\/code>, <code>\/wp-sitemap.xml<\/code> and any child sitemaps; if none found, auto-generates <code>sitemap.xml<\/code> from the crawled URL list. Emits the configured <code>robots.txt<\/code>.<\/li>\n<li>Deployer hashes each file, asks Cloudflare which assets are new, uploads only the new ones in batches (100 files \/ 25 MiB each), then creates a deployment via multipart\/form-data.<\/li>\n<li>Result: a new Cloudflare Pages deployment URL, logged with a clickable link.<\/li>\n<\/ol>\n\n<h4>What is NOT bundled<\/h4>\n\n<p>By default, files under <code>\/wp-content\/uploads\/<\/code>, theme assets, plugin assets, and fonts under <code>\/wp-content\/<\/code> are kept pointing at your WordPress origin so they keep working without re-uploading multi-gigabyte media folders. Make sure your origin is reachable over HTTPS (proxy through Cloudflare if your origin's SSL cert is fragile).<\/p>\n\n<p>If your origin can't be reached from Cloudflare (shared hosting firewall, IP allow-list, no proxy option), enable <strong>Export Scope \u2192 Bundle <code>\/wp-content\/uploads\/<\/code> into deploy<\/strong>. The plugin then fetches every uploads URL referenced in the rendered HTML and ships those files inside the CF Pages deploy itself \u2014 no origin dependency at runtime. Theme\/plugin assets still load from origin. See the <strong>Bundle <code>\/wp-content\/uploads\/<\/code> (recommended for shared hosting)<\/strong> section below.<\/p>\n\n<h4>Why this plugin<\/h4>\n\n<ul>\n<li>Simpler scope \u2014 Cloudflare Pages only, Direct Upload only.<\/li>\n<li>Built-in setup walkthrough, no docs hunting.<\/li>\n<li>Live progress UI with granular per-batch logging.<\/li>\n<li>Free tier compatible \u2014 no build minutes consumed.<\/li>\n<li>SEO baseline included \u2014 no extra plugin needed for tags + JSON-LD.<\/li>\n<li>No external dependencies, no SaaS, no premium tier.<\/li>\n<\/ul>\n\n<h3>External services<\/h3>\n\n<p>This plugin connects to the <strong>Cloudflare Pages API<\/strong> (<code>https:\/\/api.cloudflare.com\/client\/v4<\/code>) to deploy your exported static site. This is required core functionality \u2014 without it the plugin cannot upload your site to Cloudflare.<\/p>\n\n<p><strong>What the service is and what it is used for:<\/strong>\nCloudflare Pages is a static site hosting platform operated by Cloudflare, Inc. The plugin uses the Cloudflare Pages Direct Upload API to publish your statically rendered WordPress site to a Cloudflare Pages project that you create and own.<\/p>\n\n<p><strong>What data is sent, and when:<\/strong>\nThe plugin contacts the Cloudflare Pages API on these occasions:<\/p>\n\n<ul>\n<li>When you click <strong>Test Connection<\/strong> in the plugin settings. Sent: your Cloudflare API token (in the <code>Authorization<\/code> header), your Account ID, and your Pages project slug. Used to verify the project exists and the token has access.<\/li>\n<li>When you click <strong>Rebuild + Deploy Now<\/strong>, or after any post\/page\/CPT publish\/update if <strong>Auto-deploy<\/strong> is enabled (debounced). The plugin: (1) requests a short-lived upload JWT from <code>\/pages\/projects\/{project}\/upload-token<\/code>; (2) sends a list of SHA-256 hashes of the files in the export to <code>\/pages\/assets\/check-missing<\/code> to find which files Cloudflare does not already have; (3) uploads only the missing assets (HTML, CSS, JS, images, sitemap.xml, robots.txt) to <code>\/pages\/assets\/upload<\/code>; (4) POSTs a final deployment manifest + branch name to <code>\/pages\/projects\/{project}\/deployments<\/code>. All requests include your API token in the <code>Authorization: Bearer<\/code> header.<\/li>\n<\/ul>\n\n<p><strong>What is NOT sent:<\/strong> the plugin never sends WordPress database credentials, user passwords, post drafts, private content, settings beyond the four Cloudflare credentials, or any analytics\/telemetry beacons. Only the rendered public HTML\/CSS\/JS\/asset files that already make up your site are uploaded \u2014 the same content visitors would see.<\/p>\n\n<p><strong>Cloudflare Pages service links:<\/strong><\/p>\n\n<ul>\n<li>Cloudflare Pages product page: <a href=\"https:\/\/pages.cloudflare.com\/\">https:\/\/pages.cloudflare.com\/<\/a><\/li>\n<li>Cloudflare API documentation: <a href=\"https:\/\/developers.cloudflare.com\/api\/\">https:\/\/developers.cloudflare.com\/api\/<\/a><\/li>\n<li>Cloudflare Terms of Service: <a href=\"https:\/\/www.cloudflare.com\/website-terms\/\">https:\/\/www.cloudflare.com\/website-terms\/<\/a><\/li>\n<li>Cloudflare Self-Service Subscription Agreement (covers Workers &amp; Pages): <a href=\"https:\/\/www.cloudflare.com\/terms\/\">https:\/\/www.cloudflare.com\/terms\/<\/a><\/li>\n<li>Cloudflare Privacy Policy: <a href=\"https:\/\/www.cloudflare.com\/privacypolicy\/\">https:\/\/www.cloudflare.com\/privacypolicy\/<\/a><\/li>\n<\/ul>\n\n<p>You retain full ownership and control of your Cloudflare account, Pages project, API token, and deployed content. To stop using the service, revoke the API token in your Cloudflare dashboard and deactivate the plugin.<\/p>\n\n<h3>About<\/h3>\n\n<p>Built by <a href=\"https:\/\/www.gunjanjaswal.me\">Gunjan Jaswal<\/a>. Bug reports, feedback: hello@gunjanjaswal.me.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>staticforge-for-cloudflare-pages<\/code> folder to <code>\/wp-content\/plugins\/<\/code>, OR install the zip via Plugins \u2192 Add New \u2192 Upload Plugin.<\/li>\n<li>Activate <strong>StaticForge for Cloudflare Pages<\/strong> through the Plugins menu.<\/li>\n<li>Go to <strong>StaticForge for Cloudflare Pages<\/strong> in the admin sidebar.<\/li>\n<li>Open the <strong>Setup Guide<\/strong> (linked at the top of the settings page) and follow the 6 steps:\n\n<ul>\n<li>Create a Cloudflare Pages project in <em>Direct Upload<\/em> mode.<\/li>\n<li>Create an API Token with <code>Account \u2192 Cloudflare Pages \u2192 Edit<\/code> permission.<\/li>\n<li>Copy your Cloudflare Account ID.<\/li>\n<li>Paste those values + project slug + <code>main<\/code> branch + your <code>&lt;project&gt;.pages.dev<\/code> URL into the plugin settings.<\/li>\n<li>Save \u2192 Test Connection \u2192 Rebuild + Deploy Now.<\/li>\n<\/ul><\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20this%20work%20with%20the%20free%20cloudflare%20pages%20tier%3F\"><h3>Does this work with the free Cloudflare Pages tier?<\/h3><\/dt>\n<dd><p>Yes. Direct Upload deployments don't consume build minutes. There's a soft cap of about 100 deployments per day per project \u2014 the plugin's debounce setting (default 120 seconds) keeps you well under that for normal editorial workflows.<\/p><\/dd>\n<dt id=\"does%20the%20seo%20injection%20conflict%20with%20yoast%20%2F%20rank%20math%20%2F%20aio%20seo%20%2F%20schema%20plugins%3F\"><h3>Does the SEO injection conflict with Yoast \/ Rank Math \/ AIO SEO \/ Schema plugins?<\/h3><\/dt>\n<dd><p>No \u2014 two-tier dedup is built in.<\/p>\n\n<p><strong>General SEO plugins<\/strong> (handle everything: meta + og + schema) \u2014 when any of these is detected, ALL our injection is skipped: Yoast SEO (free or Premium), Rank Math, All in One SEO Pack (v4+ and legacy), SEOPress, The SEO Framework, Slim SEO, Squirrly, SmartCrawl, WP Meta SEO.<\/p>\n\n<p><strong>Schema-only plugins<\/strong> (handle only JSON-LD) \u2014 when any of these is detected, ONLY our JSON-LD is skipped, but our meta description, robots, canonical, Open Graph, and Twitter Card tags still emit so you don't lose social previews: Schema &amp; Structured Data for WP &amp; AMP (saswp by Magazine3), Schema Pro, WPSSO Core, Schema (by Hesham), Schema App, Magazine3 Schema variants.<\/p>\n\n<p>Niche plugin not in either list? Extend detection via the <code>sforge_seo_competing_plugin<\/code> filter (general) or <code>sforge_schema_competing_plugin<\/code> filter (schema-only), or simply untick the \"Inject SEO meta\" setting.<\/p><\/dd>\n<dt id=\"how%20does%20the%20sitemap%20generator%20decide%20what%20to%20include%3F\"><h3>How does the sitemap generator decide what to include?<\/h3><\/dt>\n<dd><p>If the plugin can reach <code>sitemap.xml<\/code>, <code>sitemap_index.xml<\/code>, or <code>wp-sitemap.xml<\/code> on your origin, it mirrors that as-is (including all child sitemaps for sitemap-index files).<\/p>\n\n<p>If none are reachable, the plugin generates <code>sitemap.xml<\/code> itself from the <strong>Sitemap Generator<\/strong> settings (StaticForge for Cloudflare Pages \u2192 Settings \u2192 Sitemap Generator):<\/p>\n\n<ul>\n<li><strong>Post Types<\/strong> \u2014 multi-checkbox of public post types. Default: post + page.<\/li>\n<li><strong>Include Homepage<\/strong> \u2014 adds the front page and posts page (if separate).<\/li>\n<li><strong>Include Taxonomy archives<\/strong> \u2014 all public taxonomy term archives.<\/li>\n<li><strong>Include Author archives<\/strong> \u2014 authors with at least one published post.<\/li>\n<li><strong>Split into multiple files<\/strong> \u2014 off (single <code>sitemap.xml<\/code>) or on (a <code>&lt;sitemapindex&gt;<\/code> referencing per-type sub-sitemaps such as <code>sitemap-post.xml<\/code>, <code>sitemap-page.xml<\/code>, <code>sitemap-authors.xml<\/code>, <code>sitemap-taxonomy-category.xml<\/code>).<\/li>\n<\/ul>\n\n<p>Sitemap inclusion is independent of Export Scope, so you can export a CPT without listing it in the sitemap and vice versa. Filter <code>sforge_sitemap_groups<\/code> exposes the grouped URL list for custom modification.<\/p>\n\n<p>The activity log shows which path was taken: <code>Sitemap mirrored from origin: ...<\/code> vs <code>Sitemap generated locally (single mode|split mode): N URLs ...<\/code>.<\/p><\/dd>\n<dt id=\"how%20do%20i%20get%20clean%20%2Fwp-content%2F%20urls%20on%20the%20live%20site%3F\"><h3>How do I get clean \/wp-content\/ URLs on the live site?<\/h3><\/dt>\n<dd><p>By default the plugin keeps <code>\/wp-content\/*<\/code> URLs (theme CSS\/JS, plugin assets, uploads) pointing at the WordPress origin so those assets keep working without bundling multi-gigabyte folders in every deploy. Structured data (<code>og:image<\/code>, JSON-LD <code>image<\/code>\/<code>logo<\/code>\/<code>thumbnailUrl<\/code>) and <code>&lt;img src&gt;<\/code> will therefore reference your dashboard host on the deployed site.<\/p>\n\n<p>To make every URL on the deployed site reference the live host, you need a proxy on the live host that forwards <code>\/wp-content\/*<\/code> requests back to the WordPress dashboard, and then tick <strong>Export Scope \u2192 Rewrite <code>\/wp-content\/<\/code> URLs<\/strong> in the plugin settings.<\/p>\n\n<p><strong>Cloudflare Worker (recommended).<\/strong> Create a Worker (<code>Workers &amp; Pages \u2192 Create application \u2192 Workers \u2192 Hello World<\/code>) with this code:<\/p>\n\n<p>export default {\n    async fetch(request) {\n      const url = new URL(request.url);\n      if (url.pathname.startsWith('\/wp-content\/')) {\n        url.hostname = 'dashboard.example.com';\n        return fetch(url, request);\n      }\n      return fetch(request);\n    }\n  };<\/p>\n\n<p>Replace <code>dashboard.example.com<\/code> with your actual dashboard host. Deploy, then add routes <code>example.com\/wp-content\/*<\/code> and <code>www.example.com\/wp-content\/*<\/code> under the Worker's Triggers tab.<\/p>\n\n<p><strong>Nginx \/ Apache reverse proxy.<\/strong> On the live host:<\/p><\/dd>\n<dt id=\"nginx\"><h3>Nginx<\/h3><\/dt>\n<dd><p>location \/wp-content\/ {\n      proxy_pass         https:\/\/dashboard.example.com;\n      proxy_set_header   Host dashboard.example.com;\n      proxy_ssl_server_name on;\n  }<\/p>\n\n<p>Verify with <code>curl -I https:\/\/example.com\/wp-content\/uploads\/some-file.jpg<\/code> \u2014 it should return HTTP 200 with the image content-type. Only then tick the <strong>Rewrite <code>\/wp-content\/<\/code> URLs<\/strong> setting and <strong>Rebuild + Deploy Now<\/strong>.<\/p>\n\n<p>If the toggle is on but no proxy is set up, every image, theme stylesheet, and plugin script on the deployed site will return 404.<\/p>\n\n<p>The full step-by-step is also available inside the plugin: <strong>StaticForge for Cloudflare Pages \u2192 Setup Guide \u2192 Clean \/wp-content\/ URLs (advanced)<\/strong>.<\/p><\/dd>\n<dt id=\"how%20do%20i%20serve%20images%20when%20my%20origin%20firewall%20blocks%20cloudflare%3F\"><h3>How do I serve images when my origin firewall blocks Cloudflare?<\/h3><\/dt>\n<dd><p>Shared-hosting servers (HostArmada, SiteGround, GoDaddy, etc.) often block traffic from Cloudflare Workers \/ proxy IPs. Symptoms: the proxy approach above returns <code>522<\/code> or <code>520<\/code> for <code>\/wp-content\/uploads\/*<\/code>, while a direct browser request to <code>dashboard.example.com<\/code> works fine. You usually cannot whitelist Cloudflare's edge IPs on shared hosting.<\/p>\n\n<p>Solution: tick <strong>Export Scope \u2192 Bundle <code>\/wp-content\/uploads\/<\/code> into deploy<\/strong> (leave <strong>Rewrite <code>\/wp-content\/<\/code> URLs<\/strong> off). The plugin then:<\/p>\n\n<ol>\n<li>Scans every rendered page for <code>\/wp-content\/uploads\/...<\/code> references (<code>&lt;img src&gt;<\/code>, <code>srcset<\/code>, <code>og:image<\/code>, JSON-LD <code>image<\/code>\/<code>logo<\/code>\/<code>thumbnailUrl<\/code>, inline CSS <code>url()<\/code>, oEmbed thumbnails).<\/li>\n<li>Fetches each unique file from your origin during rebuild.<\/li>\n<li>Uploads them into the Cloudflare Pages deploy at their original <code>\/wp-content\/uploads\/...<\/code> paths.<\/li>\n<li>Rewrites image URLs in HTML\/JSON-LD to the live host so the static site is fully self-contained.<\/li>\n<\/ol>\n\n<p>Theme CSS\/JS and plugin assets still load from the origin (those rarely cause shared-hosting firewall issues). Cost scales with what's actually referenced \u2014 only files used by exported pages get bundled, not the entire media library. Cloudflare's <code>check-missing<\/code> API deduplicates unchanged files between deploys so subsequent rebuilds only upload new images.<\/p>\n\n<p>Verify after deploy: <code>curl -I https:\/\/example.com\/wp-content\/uploads\/&lt;any-image&gt;.jpg<\/code> should return <code>HTTP 200<\/code> with <code>Server: cloudflare<\/code> (served by CF Pages, not your origin).<\/p><\/dd>\n<dt id=\"how%20is%20faq%20schema%20auto-detected%3F\"><h3>How is FAQ schema auto-detected?<\/h3><\/dt>\n<dd><p>The plugin scans your post for any of: Yoast FAQ blocks, Rank Math FAQ blocks, SEOPress FAQ blocks, OR native HTML5 <code>&lt;details&gt;&lt;summary&gt;Question&lt;\/summary&gt;Answer&lt;\/details&gt;<\/code> markup. If found, a <code>FAQPage<\/code> schema with <code>Question<\/code> \/ <code>Answer<\/code> items is emitted.<\/p><\/dd>\n<dt id=\"how%20is%20howto%20schema%20auto-detected%3F\"><h3>How is HowTo schema auto-detected?<\/h3><\/dt>\n<dd><p>The plugin scans your post for: Yoast HowTo blocks, Rank Math HowTo blocks. As a fallback, posts whose title starts with \"How to\" \/ \"How To\" and that contain an ordered list (<code>&lt;ol&gt;<\/code>) with 3 or more items are also recognised \u2014 each list item becomes a <code>HowToStep<\/code>.<\/p><\/dd>\n<dt id=\"is%20the%20json-ld%20output%20search-engine-valid%3F\"><h3>Is the JSON-LD output search-engine-valid?<\/h3><\/dt>\n<dd><p>Yes \u2014 the schemas follow schema.org spec with proper <code>@id<\/code> linking between Article \u2194 Author \u2194 Organization, <code>mainEntity<\/code> linking on ProfilePage, <code>BreadcrumbList<\/code> with <code>position<\/code> indexing, and <code>EntryPoint<\/code> for the homepage SearchAction. Validate with Google's Rich Results Test or schema.org Validator.<\/p><\/dd>\n<dt id=\"what%20does%20the%20author%20page%20schema%20look%20like%3F\"><h3>What does the author page schema look like?<\/h3><\/dt>\n<dd><p>A <code>Person<\/code> node (display name, URL, bio from user description, avatar 256\u00d7256 ImageObject, <code>sameAs<\/code> array of social URLs from <code>user_url<\/code> + Twitter\/Facebook\/LinkedIn\/Instagram\/YouTube\/GitHub user meta) plus a <code>ProfilePage<\/code> node that links to the Person via <code>mainEntity<\/code>. Both inside a single <code>@graph<\/code> so search engines see them as a unit.<\/p><\/dd>\n<dt id=\"are%20images%20and%20uploads%20bundled%20in%20the%20deploy%3F\"><h3>Are images and uploads bundled in the deploy?<\/h3><\/dt>\n<dd><p>No. The plugin keeps URLs under <code>\/wp-content\/*<\/code> pointing at your WordPress origin host. This avoids re-uploading gigabytes of media on every deploy. Make sure your origin is reachable over HTTPS.<\/p><\/dd>\n<dt id=\"how%20is%20the%20editable%20robots.txt%20different%20from%20the%20dashboard%27s%20robots.txt%3F\"><h3>How is the editable robots.txt different from the dashboard's robots.txt?<\/h3><\/dt>\n<dd><p>The plugin deploys a separate <code>robots.txt<\/code> to your Cloudflare Pages site root \u2014 that's the one search engines see when crawling your live domain. Your WordPress dashboard's own <code>robots.txt<\/code> (which usually says <code>Disallow: \/<\/code> to keep the backend out of search) stays put on the dashboard and is unaffected.<\/p><\/dd>\n<dt id=\"how%20long%20does%20the%20first%20deploy%20take%3F\"><h3>How long does the first deploy take?<\/h3><\/dt>\n<dd><p>A site with ~450 pages typically takes 2\u20133 minutes to render and 30\u201390 seconds to upload, on a moderately spec'd shared host. Subsequent deploys are much faster: only changed pages get re-uploaded, thanks to content-addressable hashing.<\/p><\/dd>\n<dt id=\"can%20i%20customise%20the%20url%20list%3F\"><h3>Can I customise the URL list?<\/h3><\/dt>\n<dd><p>Yes \u2014 filter <code>sforge_url_list<\/code> to add or remove URLs. Filter <code>sforge_sitemap_candidates<\/code> to add custom sitemap locations.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>New: <strong>Bundle <code>\/wp-content\/uploads\/<\/code> into deploy<\/strong> setting \u2014 when ticked, the plugin scans every rendered page for uploads URLs (<code>&lt;img src&gt;<\/code>, <code>srcset<\/code>, <code>og:image<\/code>, JSON-LD <code>image<\/code>\/<code>logo<\/code>\/<code>thumbnailUrl<\/code>, inline CSS <code>url()<\/code>, oEmbed thumbnails), fetches each file from the origin during rebuild, and ships them inside the Cloudflare Pages deploy at their original paths. Designed for shared-hosting origins (HostArmada, SiteGround, etc.) whose firewall blocks Cloudflare Worker \/ proxy IPs, making the standard <code>\/wp-content\/*<\/code> proxy approach return 520\/522. Theme\/plugin assets still load from origin; uploads cost scales with files actually referenced (CF dedupes unchanged hashes between deploys).<\/li>\n<li>Fix: <code>*.pages.dev<\/code> 301 redirect is now a client-side JS snippet injected into every page rather than a <code>functions\/_middleware.js<\/code> Pages Function. The Direct Upload API does not compile a <code>functions\/<\/code> directory or activate <code>_worker.js<\/code> advanced mode \u2014 those files are stored as static assets and never execute \u2014 so the previous server-side approach silently did nothing. The new JS redirect runs synchronously before any paint, preserves <code>path + query + hash<\/code>, and works on every deploy regardless of upload method. Canonical \/ og:url \/ JSON-LD continue to point at the live host so SEO consolidation remains correct.<\/li>\n<li>Plugin renamed from \"Send Static to Pages\" to \"StaticForge for Cloudflare Pages\". Folder slug, main file, text domain, all class\/constant\/function\/option prefixes (<code>SSTP_<\/code>\/<code>sstp_<\/code> \u2192 <code>SFORGE_<\/code>\/<code>sforge_<\/code>), and the <code>sstp_full_rebuild<\/code> cron hook moved over together.<\/li>\n<li>One-time migration on <code>plugins_loaded<\/code> (priority 1): legacy <code>sstp_settings<\/code>, <code>sstp_log<\/code>, and any pending <code>sstp_full_rebuild<\/code> cron event are copied\/rescheduled to the new keys\/hook so existing installs upgrade without losing configuration. Guarded by a <code>sforge_migrated_from_sstp<\/code> flag.<\/li>\n<li><code>uninstall.php<\/code> now also removes legacy <code>sstp_*<\/code> keys and clears the <code>sstp_full_rebuild<\/code> cron hook.<\/li>\n<li>WordPress 7.0 tested and audited \u2014 no deprecated API usage; admin-only integration so the iframed editor in WP 7.0 has no functional impact.<\/li>\n<li>WordPress 7.0 Connectors API integration: registers a <code>deployment_target<\/code> connector (<code>sforge-cloudflare-pages<\/code>) on the <code>wp_connectors_init<\/code> action so the plugin appears on the central Connections screen and links back to the StaticForge settings page for credential management. Falls back silently on WP &lt; 7.0.<\/li>\n<li>Added plugin action links \u2014 <code>Settings<\/code> and <code>Support on Ko-fi<\/code> next to Deactivate.<\/li>\n<li>Added plugin row meta \u2014 <code>Plugin Support<\/code> (WordPress.org forum) and <code>Contact Developer<\/code>.<\/li>\n<li>Donate link moved to Ko-fi (https:\/\/ko-fi.com\/gunjanjaswal).<\/li>\n<\/ul>\n\n<h4>1.0.1<\/h4>\n\n<ul>\n<li>New: social-aware dashboard noindex \u2014 robots.txt now explicitly allows <code>\/wp-content\/uploads\/<\/code> for facebookexternalhit \/ facebookcatalog \/ Twitterbot \/ LinkedInBot \/ Pinterestbot \/ WhatsApp \/ Slackbot \/ Discordbot \/ TelegramBot \/ Applebot \/ redditbot \/ Tumblr \/ iframely \/ Embedly \/ Mastodon \/ Bluesky \/ meta-externalagent. The <code>X-Robots-Tag<\/code> HTTP header is also skipped for media paths and social-scraper user agents so og:image previews resolve correctly when posts are shared.<\/li>\n<li>New: <code>*.pages.dev<\/code> 301-redirect middleware \u2014 when the configured Public Site URL is a custom domain, the plugin emits <code>functions\/_middleware.js<\/code> into the deploy that intercepts requests to <code>&lt;project&gt;.pages.dev<\/code> and permanently redirects them to the canonical live host. Auto-skipped when Public Site URL is itself a <code>.pages.dev<\/code> URL.<\/li>\n<li>New: opt-in <strong>Rewrite <code>\/wp-content\/<\/code> URLs<\/strong> setting plus a \"Clean \/wp-content\/ URLs (advanced)\" section in the in-plugin Setup Guide and README covering Cloudflare Worker and Nginx\/Apache reverse-proxy setups for fully clean live URLs (og:image, JSON-LD image\/logo, srcset).<\/li>\n<li>New: standalone Person + ProfilePage JSON-LD module for author archives (emits even when an SEO plugin is active, with distinct <code>@id<\/code> suffix). sameAs auto-collected from user_url + user_meta for Twitter\/X, Facebook, LinkedIn, Instagram, YouTube, GitHub, Pinterest, TikTok, Threads, Medium, Mastodon, Bluesky. Optional <code>jobTitle<\/code> \/ <code>worksFor<\/code> from custom meta.<\/li>\n<li>New: dashboard auto-noindex on activation \u2014 physical <code>Disallow: \/<\/code> robots.txt at webroot (existing file backed up to <code>robots.txt.sforge-backup<\/code>), <code>wp_robots<\/code> filter, <code>X-Robots-Tag<\/code> HTTP header, <code>robots_txt<\/code> filter. Plugin's own export fetches are exempt via <code>X-SFORGE-Export<\/code> header. Restored on deactivation.<\/li>\n<li>New: fallback sitemap.xml \u2014 when origin has no sitemap, plugin builds a standards-compliant <code>&lt;urlset&gt;<\/code> from native WP data (homepage + selected post types + taxonomy term archives + author archives).<\/li>\n<li>New: granular sitemap generator settings \u2014 per-post-type checkboxes, include\/exclude homepage \/ taxonomies \/ authors, and a split-mode toggle that emits a <code>&lt;sitemapindex&gt;<\/code> referencing per-type sub-sitemaps. Filter: <code>sforge_sitemap_groups<\/code>.<\/li>\n<li>New: featured image LCP boost \u2014 auto-adds <code>fetchpriority=\"high\"<\/code>, <code>loading=\"eager\"<\/code>, <code>decoding=\"async\"<\/code> on the post's featured image. Works on any theme using <code>the_post_thumbnail()<\/code> \/ <code>get_the_post_thumbnail()<\/code>.<\/li>\n<li>New: activity-log visibility for sitemap decisions \u2014 distinguishes \"mirrored from origin\" vs \"generated locally (single|split mode)\" vs explicit warnings when fallback yields no groups.<\/li>\n<li>New: auto-backfill new option defaults on <code>plugins_loaded<\/code> so existing installs pick up new settings without a deactivate\/reactivate.<\/li>\n<li>Improved: URL rewriter now also handles escaped forward slashes (<code>https:\\\/\\\/origin\\\/...<\/code>) so JSON-LD, REST embeds, and inline JSON payloads get rewritten to the public host. <code>\/wp-content\/<\/code> skip preserved in both literal and escaped forms.<\/li>\n<li>Improved: mirrored sitemaps now strip <code>&lt;?xml-stylesheet ... ?&gt;<\/code> directives and rewrite protocol-relative <code>\/\/host<\/code> references so the dashboard host doesn't leak into the public sitemap.<\/li>\n<li>Improved: <code>Sitemap:<\/code> line in custom robots.txt is auto-managed \u2014 any user-typed directive is stripped and replaced with the actual deployed sitemap path (sitemap.xml \/ sitemap_index.xml \/ wp-sitemap.xml \/ etc.) so the URL is never broken.<\/li>\n<li>Improved: settings page redesign \u2014 colour-coded section cards, hero header, status pill, live activity log, \"Setup Guide\" link.<\/li>\n<li>Improved: filemtime-based cache busting on plugin admin CSS\/JS so settings UI updates show immediately.<\/li>\n<li>Improved: deploy log now reports per-batch upload progress (count + size + duration + cumulative total).<\/li>\n<li>Improved: bumped PHP memory limit to 512 MB during full rebuild.<\/li>\n<li>Improved: multipart\/form-data deployment POST (was URL-encoded \u2014 Cloudflare rejected as \"Request body is incorrect\").<\/li>\n<li>Improved: Dashicons explicitly enqueued as a stylesheet dependency on plugin admin pages.<\/li>\n<li>Improved: \"Rebuild + Deploy Now\" \/ \"Test Connection\" \/ \"Clear Log\" now scroll to and briefly highlight the Activity Log section.<\/li>\n<li>Fix: fatal parse error caused by <code>?&gt;<\/code> inside a <code>\/\/<\/code> line comment terminating the <code>&lt;?php<\/code> block. Replaced with block comment.<\/li>\n<li>Fix: CDATA-wrapped <code>&lt;loc&gt;<\/code> entries in sitemap-index files now expand correctly to child sitemap URLs.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial public release.<\/li>\n<li>Cloudflare Pages Direct Upload API client (multipart\/form-data deployment).<\/li>\n<li>Whole-site crawl: posts, pages, custom post types, taxonomy and author archives, homepage.<\/li>\n<li>CSS inlining for self-contained pages.<\/li>\n<li>Featured image LCP boost: <code>fetchpriority=\"high\"<\/code>, <code>loading=\"eager\"<\/code>, <code>decoding=\"async\"<\/code>.<\/li>\n<li>Built-in SEO metadata injection: meta description, robots, canonical, Open Graph, Twitter Card.<\/li>\n<li>JSON-LD schemas: WebSite + SearchAction, Organization, Article, WebPage, Person + ProfilePage on author archives, CollectionPage on taxonomy archives, BreadcrumbList, auto-detected FAQPage and HowTo.<\/li>\n<li>Two-tier dedup: auto-pause all injection on general SEO plugins (Yoast, Rank Math, AIO SEO, SEOPress, The SEO Framework, Slim SEO, Squirrly, SmartCrawl, WP Meta SEO); pause only JSON-LD on schema-only plugins (saswp, Schema Pro, WPSSO, Schema by Hesham, Schema App, Magazine3 Schema variants).<\/li>\n<li>Sitemap mirroring with CDATA-wrapped <code>&lt;loc&gt;<\/code> support, <code>&lt;?xml-stylesheet ?&gt;<\/code> strip, and protocol-relative URL rewriting.<\/li>\n<li>Fallback sitemap.xml auto-generated from the crawled URL list when origin exposes none.<\/li>\n<li>Granular sitemap generator settings: per-post-type, homepage, taxonomies, authors, single vs split (sitemapindex + per-type sub-sitemaps).<\/li>\n<li>Editable robots.txt for the live site with auto-managed <code>Sitemap:<\/code> directive matching the actually-deployed sitemap path.<\/li>\n<li>Auto-backfill of new option keys on plugin update so existing installs pick up new defaults without deactivate\/reactivate.<\/li>\n<li>Dashboard auto-noindex on activation (physical robots.txt + filters + X-Robots-Tag header), restored on deactivation.<\/li>\n<li>Defensive noindex stripping on export.<\/li>\n<li>Auto-deploy on publish\/update with configurable debounce.<\/li>\n<li>Live activity log with auto-refresh and status indicator.<\/li>\n<li>Built-in Setup Guide page and WordPress contextual Help tabs.<\/li>\n<\/ul>","raw_excerpt":"Auto-export WordPress as static HTML to Cloudflare Pages on publish \u2014 with SEO meta, JSON-LD schemas, sitemaps, and robots.txt.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/315673","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=315673"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/gunjanjaswal"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=315673"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=315673"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=315673"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=315673"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=315673"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=315673"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}