{"id":355555,"date":"2026-08-17T20:45:48","date_gmt":"2026-08-17T20:45:48","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/grovik-publisher\/"},"modified":"2026-08-17T22:05:29","modified_gmt":"2026-08-17T22:05:29","slug":"grovik-publisher","status":"publish","type":"plugin","link":"https:\/\/tzm.wordpress.org\/plugins\/grovik-publisher\/","author":23205288,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"2.3.0","stable_tag":"2.3.0","tested":"7.1","requires":"5.3","requires_php":"7.4","requires_plugins":null,"header_name":"Grovik Publisher","header_author":"Grovik","header_description":"Lets Grovik (grovik.ai) publish SEO articles directly to this WordPress site via a dedicated API key \u2014 independent of WordPress's own Application Passwords, so it isn't affected by security plugins that disable those. Install, generate a key, paste it into your Grovik dashboard's Publishing settings.","assets_banners_color":"b8c2c3","last_updated":"2026-08-17 22:05:29","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/grovik.ai","rating":0,"author_block_rating":0,"active_installs":0,"downloads":46,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"2.2.1":{"tag":"2.2.1","author":"mikkelholmnielsen","date":"2026-08-17 21:33:53"},"2.3.0":{"tag":"2.3.0","author":"mikkelholmnielsen","date":"2026-08-17 22:05:29"}},"upgrade_notice":{"2.2.1":"<p>Security update: publishing no longer signs a WordPress user in for the request. Articles and images are still attributed to your chosen author. Recommended for all sites.<\/p>","2.2.0":"<p>Security update: article content is now filtered through wp_kses_post() before being saved. Adds a connection status panel and masks the API key on screen. Recommended for all sites.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3651708,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3651709,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3651718,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3651719,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["2.2.1","2.3.0"],"block_files":[],"assets_screenshots":[],"screenshots":[]},"plugin_section":[],"plugin_tags":[2353,569,529,7143,186],"plugin_category":[55],"plugin_contributors":[276168],"plugin_business_model":[],"class_list":["post-355555","plugin","type-plugin","status-publish","hentry","plugin_tags-ai","plugin_tags-automation","plugin_tags-content","plugin_tags-publishing","plugin_tags-seo","plugin_category-seo-and-marketing","plugin_contributors-mikkelholmnielsen","plugin_committers-mikkelholmnielsen"],"banners":{"banner":"https:\/\/ps.w.org\/grovik-publisher\/assets\/banner-772x250.png?rev=3651719","banner_2x":"https:\/\/ps.w.org\/grovik-publisher\/assets\/banner-1544x500.png?rev=3651718","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/grovik-publisher\/assets\/icon-128x128.png?rev=3651708","icon_2x":"https:\/\/ps.w.org\/grovik-publisher\/assets\/icon-256x256.png?rev=3651709","generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Grovik Publisher is the bridge between your WordPress site and Grovik \u2014 an\nSEO content service that decides what to write about, writes it, and puts it\nlive here on a schedule you set.<\/p>\n\n<p><strong>This plugin does not generate content by itself.<\/strong> It is the publishing end\nof a service that does the work before an article ever reaches your site:<\/p>\n\n<ul>\n<li><strong>Keyword research against real search data.<\/strong> Grovik pulls actual monthly\nsearch volumes and competition figures, then picks the topics worth writing\nabout for your site specifically \u2014 not a generic list.<\/li>\n<li><strong>Articles written in your site's own voice.<\/strong> Grovik reads your existing\ncontent first and builds a profile of how you write, so new articles sound\nlike the rest of your site instead of like a text generator.<\/li>\n<li><strong>Internal links that fit.<\/strong> Every article is linked to the pages you\nalready have, using the anchor text that makes sense \u2014 the part of SEO\ncontent that is normally left undone.<\/li>\n<li><strong>A publishing schedule, not a queue you babysit.<\/strong> You decide the cadence;\nGrovik fills the calendar and publishes on its own.<\/li>\n<li><strong>Featured images included.<\/strong> Each article arrives with an image, which this\nplugin downloads into your own Media Library.<\/li>\n<\/ul>\n\n<p>What the plugin adds on the WordPress side:<\/p>\n\n<ul>\n<li>A dedicated API key generated on this site, independent of WordPress's own\nApplication Passwords \u2014 so it keeps working even if a security plugin such\nas Wordfence disables those.<\/li>\n<li>No WordPress username involved anywhere: just this site's URL and the key.<\/li>\n<li>A connection status panel showing whether Grovik has reached your site, when\nit last published, and how many articles it has published in total.<\/li>\n<li>A default author and category applied to every article Grovik publishes.<\/li>\n<li>One-click key rotation \u2014 generating a new key revokes the old one instantly.<\/li>\n<li>Unpublish, re-publish and delete straight from Grovik, without opening\nwp-admin. Deletes go to Trash, so they stay recoverable.<\/li>\n<\/ul>\n\n<h4>See what your site needs first<\/h4>\n\n<p>You do not need this plugin, or an account, to find out where your site\nstands. Grovik's <a href=\"https:\/\/grovik.ai\/audit\">free SEO audit<\/a> crawls your pages\nand reports the technical, on-page and AI-search issues holding your rankings\nback. No sign-up, no email, and every finding is shown in full.<\/p>\n\n<h4>Requires an account<\/h4>\n\n<p>Grovik Publisher is useless on its own. It does nothing until you connect it\nto a Grovik account at <a href=\"https:\/\/grovik.ai\">grovik.ai<\/a> \u2014 the plugin has no\ncontent generation in it, and nothing in it is unlocked by payment. Grovik is\na paid service with its own pricing and terms.<\/p>\n\n<h3>External services<\/h3>\n\n<p>This plugin connects your WordPress site to <strong>Grovik<\/strong>, an external SEO\ncontent service operated by Grovik at <a href=\"https:\/\/grovik.ai\">grovik.ai<\/a>. <strong>A\nGrovik account is required<\/strong> \u2014 without one, this plugin has nothing to connect\nto and will never publish anything.<\/p>\n\n<p><strong>How the connection works<\/strong><\/p>\n\n<p>The plugin does not call Grovik. It registers REST endpoints under\n    \/wp-json\/grovik\/v1\/ on your own site and waits; Grovik's servers connect\n<em>to<\/em> your site, authenticating with the API key this plugin generates. Nothing\nis transmitted anywhere when you simply install or activate the plugin, and\nnothing is transmitted when you open its settings screen.<\/p>\n\n<p><strong>What Grovik sends to your site<\/strong><\/p>\n\n<p>When Grovik publishes or updates an article, it sends the article title, the\narticle content, a URL slug, the web address of a featured image, and that\nimage's alt text. When it unpublishes or deletes, it sends the WordPress post\nID of a post it previously created here.<\/p>\n\n<p><strong>What your site sends back to Grovik<\/strong><\/p>\n\n<p>Only the direct response to each of those requests: the post ID and permalink\nof the article that was just saved, and \u2014 when Grovik tests the connection \u2014\nyour site's name, its WordPress version, and this plugin's version. Your site\nnever initiates contact with Grovik and never sends visitor data, personal\ndata, or site analytics.<\/p>\n\n<p><strong>What your site fetches from elsewhere<\/strong><\/p>\n\n<p>The one outbound request this plugin makes is downloading the featured image\nfrom the address Grovik supplies (Grovik's image storage), so the image\nbecomes a real attachment in your own Media Library rather than a hotlink.\nNo code, scripts, styles, fonts or images are ever loaded from an external\ndomain \u2014 every asset the plugin uses ships inside the plugin itself.<\/p>\n\n<p><strong>What Grovik stores about your site<\/strong><\/p>\n\n<p>You paste this site's URL and API key into your Grovik dashboard yourself, so\nGrovik holds those two values in order to reach your site. Grovik also holds\nthe content it produced for you.<\/p>\n\n<p><strong>Terms and privacy<\/strong><\/p>\n\n<ul>\n<li><a href=\"https:\/\/grovik.ai\/terms-of-service\">Terms of service<\/a><\/li>\n<li><a href=\"https:\/\/grovik.ai\/privacy-policy\">Privacy policy<\/a><\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>grovik-publisher<\/code> folder to <code>\/wp-content\/plugins\/<\/code>, or install the zip directly from Plugins \u2192 Add New \u2192 Upload Plugin.<\/li>\n<li>Activate the plugin \u2014 you'll be redirected straight to its settings screen with a freshly generated key.<\/li>\n<li>Copy the key and paste it into your Grovik dashboard's Publishing settings, along with this site's URL.<\/li>\n<li>Run \"Test connection\" in Grovik. The status panel on the plugin's settings screen will show the connection as active.<\/li>\n<li>Optionally set a default author and category for articles Grovik publishes.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"can%20i%20check%20my%20site%20before%20installing%20anything%3F\"><h3>Can I check my site before installing anything?<\/h3><\/dt>\n<dd><p>Yes. Grovik's <a href=\"https:\/\/grovik.ai\/audit\">free SEO audit<\/a> is open to anyone \u2014 no\naccount, no email, nothing hidden. It crawls your site and lists what it\nfinds. Installing this plugin is a separate decision you can make afterwards.<\/p><\/dd>\n<dt id=\"do%20i%20need%20a%20grovik%20account%3F\"><h3>Do I need a Grovik account?<\/h3><\/dt>\n<dd><p>Yes. The plugin is the publishing end of the Grovik service and does nothing\non its own \u2014 no account, no articles. Grovik is a paid service; see\n<a href=\"https:\/\/grovik.ai\">grovik.ai<\/a> for pricing.<\/p><\/dd>\n<dt id=\"does%20this%20give%20grovik%20my%20wordpress%20login%3F\"><h3>Does this give Grovik my WordPress login?<\/h3><\/dt>\n<dd><p>No. Grovik authenticates with a random API key this plugin generates, which\nonly works against this plugin's own <code>\/wp-json\/grovik\/v1\/*<\/code> endpoints and\ncan be revoked independently of any WordPress account at any time from\nthis plugin's settings screen.<\/p><\/dd>\n<dt id=\"what%20can%20grovik%20change%20on%20my%20site%3F\"><h3>What can Grovik change on my site?<\/h3><\/dt>\n<dd><p>Grovik can create blog posts, and can update or trash posts by ID. It cannot\ntouch pages, media attachments or custom post types \u2014 those are out of reach\nof the plugin's endpoints entirely.<\/p>\n\n<p>In practice Grovik only ever acts on the articles it published itself. But the\nplugin does not enforce that: anything holding your API key can update or trash\nany blog post on the site. Treat the key as what it is \u2014 full publishing access\n\u2014 and regenerate it from this plugin's settings screen if you ever suspect it\nhas leaked.<\/p><\/dd>\n<dt id=\"is%20the%20article%20content%20filtered%20before%20it%20is%20saved%3F\"><h3>Is the article content filtered before it is saved?<\/h3><\/dt>\n<dd><p>Yes. All incoming article HTML is run through WordPress's own\n    wp_kses_post() before it is stored, so scripts, iframes, inline event\nhandlers and <code>javascript:<\/code> URLs cannot reach your site \u2014 while the ordinary\narticle markup (headings, lists, tables, links, images) passes through\nuntouched.<\/p><\/dd>\n<dt id=\"why%20not%20wordpress%27s%20built-in%20application%20passwords%3F\"><h3>Why not WordPress's built-in Application Passwords?<\/h3><\/dt>\n<dd><p>An earlier version of this plugin used them. In practice, security plugins\n(Wordfence and others) can disable Application Passwords site-wide with no\nobvious indication anywhere that this is why a connection fails \u2014 every\nrequest gets rejected with the exact same generic error WordPress gives\nfor a wrong password. A key this plugin manages itself has no dependency\non that WordPress core feature being enabled at all.<\/p><\/dd>\n<dt id=\"does%20the%20settings%20screen%20contact%20grovik%3F\"><h3>Does the settings screen contact Grovik?<\/h3><\/dt>\n<dd><p>No. The connection status, the publish count and the timestamps are all\nrecorded by your own site as Grovik's requests arrive. Opening the screen\nmakes no outbound request at all.<\/p><\/dd>\n<dt id=\"what%20happens%20if%20i%20deactivate%20the%20plugin%3F\"><h3>What happens if I deactivate the plugin?<\/h3><\/dt>\n<dd><p>Deactivating does not revoke the existing key \u2014 it's meant for temporary\nsituations (a site update, debugging) where you don't want to lose the\nconnection. Uninstalling (fully deleting the plugin) removes the key and\nall of this plugin's settings. Articles already published are left in place.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>2.3.0<\/h4>\n\n<ul>\n<li>New: the SEO title and meta description Grovik writes for an article are now published with it, into Yoast SEO (<code>_yoast_wpseo_title<\/code>, <code>_yoast_wpseo_metadesc<\/code>) or Rank Math (<code>rank_math_title<\/code>, <code>rank_math_description<\/code>), whichever is active. Previously they stopped at Grovik and the article arrived here with none. Editing them in Grovik and pushing the article again updates them too.<\/li>\n<li>If neither plugin is active, nothing is written: WordPress itself has no field for these, so the values would sit in the database unread. Install either plugin and republish to fill them in.<\/li>\n<li>Updating from an older version needs nothing: articles already published keep their content, and their SEO fields are filled in the next time Grovik pushes them.<\/li>\n<\/ul>\n\n<h4>2.2.1<\/h4>\n\n<ul>\n<li>Security: publishing no longer signs a WordPress user in. Earlier versions called <code>wp_set_current_user()<\/code> around each publish and update, which made the whole request run as that user \u2014 an API key was effectively treated as proof of who was making the request. It no longer is: the routes run with no logged-in user, and the author is passed explicitly to WordPress instead. Articles are still attributed to the author chosen on the settings screen, and featured images still arrive in the Media Library owned by that same author.<\/li>\n<li>Republishing an article now keeps whichever author it currently has, so reassigning a Grovik article to another author in wp-admin sticks.<\/li>\n<li>Article content is now filtered by WordPress's own content filters as well as the plugin's <code>wp_kses_post()<\/code> call, a direct consequence of no longer running as an administrator. Ordinary article markup is unaffected.<\/li>\n<\/ul>\n\n<h4>2.2.0<\/h4>\n\n<ul>\n<li>New: a connection status panel on the settings screen \u2014 whether Grovik has reached this site, when it last published an article, and how many it has published in total. Everything on it is recorded by this site as Grovik's own requests arrive, so opening the screen makes no outbound call.<\/li>\n<li>New: the API key is now masked by default, with a Show\/Hide toggle, so it isn't exposed in screenshots or while screen-sharing. Copy still puts the real key on the clipboard in one click whether it's shown or hidden.<\/li>\n<li>Security: incoming article content is now filtered through <code>wp_kses_post()<\/code> before being stored. Previously it was saved verbatim, because WordPress only applies that filter for users without the <code>unfiltered_html<\/code> capability and this plugin publishes as an administrator. Scripts, iframes, inline event handlers and <code>javascript:<\/code> URLs can no longer reach the site.<\/li>\n<li>Security: featured image URLs are now validated and restricted to http\/https before the image is fetched.<\/li>\n<li>The settings screen was rebuilt on WordPress's own admin components, with a service disclosure section and links to documentation and support.<\/li>\n<li>Uninstalling now also clears the per-post markers this plugin set. Published articles are left alone.<\/li>\n<li>Fixed: the minimum WordPress version is now correctly declared as 5.3 \u2014 the featured image code has always required it.<\/li>\n<\/ul>\n\n<h4>2.1.1<\/h4>\n\n<ul>\n<li>Fixed: Unpublish, Delete and republishing failed on any article that was published before this site updated to 2.1.0 \u2014 the \"was this post actually created by Grovik\" safety check added in 2.1.0 only recognized posts tagged from that version onward, so every older post looked unrecognized and got rejected. Posts missing that tag are now recognized and tagged retroactively the first time Grovik touches them again, instead of being permanently locked out.<\/li>\n<\/ul>\n\n<h4>2.1.0<\/h4>\n\n<ul>\n<li>New: <code>\/wp-json\/grovik\/v1\/posts\/{id}<\/code> \u2014 lets Grovik unpublish (set back to draft), republish with edited content, or move to Trash a post it previously created, instead of only ever being able to create new ones. Every post Grovik creates is now tagged internally so these endpoints only ever act on posts Grovik itself made \u2014 never a post a site owner wrote by hand, even if the wrong ID were ever sent.<\/li>\n<li>Deleting from Grovik now moves the post to Trash (WordPress's own default, recoverable for the same window as deleting by hand in wp-admin), not a permanent delete.<\/li>\n<\/ul>\n\n<h4>2.0.0<\/h4>\n\n<ul>\n<li>Rebuilt on a Grovik-specific API key and the plugin's own REST endpoints (<code>\/wp-json\/grovik\/v1\/ping<\/code>, <code>\/wp-json\/grovik\/v1\/publish<\/code>), replacing the previous WordPress Application Passwords-based approach entirely. No more WordPress username field, no dependency on WordPress core's Application Passwords being enabled, and no longer affected by security plugins that disable them.<\/li>\n<li>The settings screen now always shows the current key (with a Copy button), not just once immediately after generating it.<\/li>\n<li>The featured image is now downloaded and attached to the post directly by this plugin (via WordPress's own media_sideload_image()), from a single publish request \u2014 Grovik no longer needs a separate image-upload call.<\/li>\n<\/ul>\n\n<h4>1.0.1<\/h4>\n\n<ul>\n<li>Fixed: the key is now generated for whichever admin activates the plugin (or clicks \"Generate key\"), instead of a separate, hidden \"grovik\" user \u2014 avoids a mismatch where the key silently belongs to a username the site owner never sees. Sites that already had a \"grovik\" user configured before this update keep using it.<\/li>\n<li>The settings screen now always shows the exact WordPress username the current key is bound to, with its own Copy button, so it's never a guess when connecting in Grovik.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release.<\/li>\n<\/ul>","raw_excerpt":"Connect your site to Grovik and let it research, write and publish SEO articles for you. Requires a Grovik account.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/tzm.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/355555","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tzm.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/tzm.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/tzm.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=355555"}],"author":[{"embeddable":true,"href":"https:\/\/tzm.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/mikkelholmnielsen"}],"wp:attachment":[{"href":"https:\/\/tzm.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=355555"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/tzm.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=355555"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/tzm.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=355555"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/tzm.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=355555"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/tzm.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=355555"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/tzm.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=355555"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}