{"id":359531,"date":"2026-08-31T09:41:47","date_gmt":"2026-08-31T09:41:47","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/hafen-core\/"},"modified":"2026-08-31T09:41:26","modified_gmt":"2026-08-31T09:41:26","slug":"hafen-core","status":"publish","type":"plugin","link":"https:\/\/cn.wordpress.org\/plugins\/hafen-core\/","author":23511618,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.0","stable_tag":"1.0.0","tested":"7.1","requires":"6.4","requires_php":"7.4","requires_plugins":null,"header_name":"Hafen Core","header_author":"hafenstudios","header_description":"Adds JSON-LD schema, an llms.txt file, answer blocks for FAQ and HowTo, an AI crawler policy and a local AI traffic dashboard.","assets_banners_color":"6758f1","last_updated":"2026-08-31 09:41:26","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/hafenstudios.com\/hafen","header_author_uri":"https:\/\/hafenstudios.com\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":32,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"hafenstudios","date":"2026-08-31 09:41:26","revision":3673784}},"upgrade_notice":{"1.0.0":"<p>First WordPress.org release. Source language is now English; translations\narrive via translate.wordpress.org. The AI assistant runs through the\nWordPress AI client. The setup wizard no longer replaces an existing\nhomepage. Review the AI crawler policy after updating.<\/p>","0.9.0":"<p>The weekly OpenAI IP range fetch previously ran automatically with the AI\ntraffic measurement; it is now its own opt-in switch (Settings &gt; AI\nTraffic), OFF by default. Anyone who wants to use bot verification must\nenable it once after the update.<\/p>","0.8.1":"<p>Security fix: the access gate did not apply to the REST API, llms.txt, the\nIndexNow key file and the Markdown delivery. Update recommended if the\naccess gate is in use.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3673808,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3673808,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3673808,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3673808,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":{"hafen\/faq":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"hafen\/faq","title":"Hafen FAQ","category":"hafen","icon":"editor-help","description":"Question-answer block that renders visibly and automatically emits FAQPage schema.","keywords":["faq","schema","aeo","fragen"],"textdomain":"hafen-core","attributes":{"title":{"type":"string","default":""},"items":{"type":"array","default":[]}},"supports":{"html":false,"anchor":true,"spacing":{"margin":true,"padding":true}},"editorScript":"hafen-core-editor","style":"hafen-core-blocks","editorStyle":"hafen-core-blocks","render":"file:.\/render.php"},"hafen\/video-consent":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"hafen\/video-consent","title":"Hafen Video (2-click)","category":"hafen","icon":"video-alt3","description":"Privacy-friendly YouTube video: loads only after a click, then via youtube-nocookie.com. No data is sent to YouTube before that.","keywords":["youtube","video","datenschutz","dsgvo","consent"],"textdomain":"hafen-core","attributes":{"videoId":{"type":"string","default":""},"title":{"type":"string","default":""},"aspectRatio":{"type":"string","default":"16\/9"}},"supports":{"html":false,"anchor":true,"align":["wide","full"],"spacing":{"margin":true,"padding":true}},"editorScript":"hafen-core-editor","style":"hafen-core-blocks","editorStyle":"hafen-core-blocks","viewScript":"hafen-core-video-consent","render":"file:.\/render.php"},"hafen\/definition":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"hafen\/definition","title":"Hafen Definition","category":"hafen","icon":"book","description":"Term and definition in the what-is-X format that LLMs like to cite.","keywords":["definition","begriff","aeo","was ist"],"textdomain":"hafen-core","attributes":{"term":{"type":"string","default":""},"definition":{"type":"string","default":""}},"supports":{"html":false,"anchor":true,"spacing":{"margin":true,"padding":true}},"editorScript":"hafen-core-editor","style":"hafen-core-blocks","editorStyle":"hafen-core-blocks","render":"file:.\/render.php"},"hafen\/key-takeaway":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"hafen\/key-takeaway","title":"Hafen TL;DR","category":"hafen","icon":"lightbulb","description":"Highlighted short answer that answer engines like to cite.","keywords":["tldr","kurzantwort","aeo","zusammenfassung"],"textdomain":"hafen-core","attributes":{"label":{"type":"string","default":"Kurzantwort"},"content":{"type":"string","default":""},"speakable":{"type":"boolean","default":true}},"supports":{"html":false,"anchor":true,"spacing":{"margin":true,"padding":true}},"editorScript":"hafen-core-editor","style":"hafen-core-blocks","editorStyle":"hafen-core-blocks","render":"file:.\/render.php"},"hafen\/howto":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"hafen\/howto","title":"Hafen HowTo","category":"hafen","icon":"editor-ol","description":"Step-by-step guide that renders visibly and automatically emits HowTo schema.","keywords":["howto","schema","schritte","anleitung"],"textdomain":"hafen-core","attributes":{"name":{"type":"string","default":""},"steps":{"type":"array","default":[]}},"supports":{"html":false,"anchor":true,"spacing":{"margin":true,"padding":true}},"editorScript":"hafen-core-editor","style":"hafen-core-blocks","editorStyle":"hafen-core-blocks","render":"file:.\/render.php"}},"tagged_versions":["1.0.0"],"block_files":[],"assets_screenshots":[],"screenshots":{"1":"Settings &gt; Hafen Core \u2013 schema mode, organization, llms.txt and performance switches.","2":"AI crawler policy \u2013 the bot matrix by purpose (training, search\/index, live retrieval) with plain-language warnings before every block.","3":"AI traffic dashboard \u2013 hits per bot, crawl-to-refer ratio per provider and the measurement quality indicator.","4":"Access gate (Under Construction) \u2013 one of the three bundled templates with automatically applied logo and accent color.","5":"The four answer engine blocks in the editor: FAQ, HowTo, TL;DR and Definition.","6":"The optional AI assistant in the editor sidebar (meta description, TL;DR and FAQ suggestions)."}},"plugin_section":[],"plugin_tags":[2353,232780,4121,1117,1121],"plugin_category":[55],"plugin_contributors":[273845],"plugin_business_model":[],"class_list":["post-359531","plugin","type-plugin","status-publish","hentry","plugin_tags-ai","plugin_tags-ai-crawler","plugin_tags-blocks","plugin_tags-schema","plugin_tags-structured-data","plugin_category-seo-and-marketing","plugin_contributors-hafenstudios","plugin_committers-hafenstudios"],"banners":{"banner":"https:\/\/ps.w.org\/hafen-core\/assets\/banner-772x250.png?rev=3673808","banner_2x":"https:\/\/ps.w.org\/hafen-core\/assets\/banner-1544x500.png?rev=3673808","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/hafen-core\/assets\/icon-128x128.png?rev=3673808","icon_2x":"https:\/\/ps.w.org\/hafen-core\/assets\/icon-256x256.png?rev=3673808","generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p><strong>The companion plugin to the <a href=\"https:\/\/wordpress.org\/themes\/hafen\/\">Hafen theme<\/a>.<\/strong>\nFollowing the principle \"theme = presentation, plugin = functionality\", Hafen\nCore carries the functionality that, per the WordPress.org guidelines, does\nnot belong in a theme: a schema engine, five answer blocks, an AI crawler\npolicy for robots.txt, a local AI traffic dashboard, Markdown delivery for\nagent clients, a citability linter, an under-construction gate and an\nllms.txt file. It works with any theme, but it is built and tested as the\nfunctional half of Hafen.<\/p>\n\n<p><strong>Access rules and measurement in one plugin.<\/strong> Most plugins in this field do\none of the two: they either block AI crawlers, or they report on AI visibility\nfrom an external service. Hafen Core does both in the same place and can\ntherefore relate them to each other, for example: \"Perplexity is not crawling\nyou, and PerplexityBot is on your block list.\" Everything runs on your own\ninstallation; no account and no external service are required for it.<\/p>\n\n<p><strong>No invented scores.<\/strong> This plugin does not calculate a visibility score\nand does not promise you a placement in ChatGPT. Where the evidence is thin, it\nsays so: llms.txt is labeled as speculative, every rule in the citability\nlinter states its evidence strength and its source, and where a provider\npublishes no IP ranges we do not present a user agent as proof. The most honest\nsentence first: the strongest documented factor for citations is mentions of\nyour brand elsewhere. On-page is the smaller lever. Everything this plugin does\nworks on that smaller lever \u2013 but it does so cleanly and verifiably.<\/p>\n\n<p><strong>Schema engine.<\/strong> Automatically embeds valid JSON-LD without you writing\nanything: Organization, WebSite (including the search action), Article (on\nposts) and BreadcrumbList. Plus FAQPage and HowTo generated from the answer\nblocks. Everything in a single @graph in the document head.<\/p>\n\n<p><strong>Answer engine blocks.<\/strong> Five blocks that render nicely for humans while\nbeing machine-readable and privacy-friendly:<\/p>\n\n<ul>\n<li>Hafen FAQ \u2014 emits FAQPage schema.<\/li>\n<li>Hafen HowTo \u2014 emits HowTo schema.<\/li>\n<li>Hafen TL;DR \u2014 highlighted short answer.<\/li>\n<li>Hafen Definition \u2014 a term in what-is-X format.<\/li>\n<li>Hafen Video (2-click) \u2014 privacy-friendly YouTube embed that loads only\nafter a click, via youtube-nocookie.com.<\/li>\n<\/ul>\n\n<p><strong>Access gate (Under Construction).<\/strong> Protect the whole website with a\npassword while it is being built \u2013 without an extra plugin. Three bundled\ntemplates (light, dark, accent gradient) automatically pick up your logo, your\nsite name and your accent color. Logged-in users see the website normally, the\ngate page sends HTTP 503 + noindex (safe for SEO), and the WordPress logo on\nlogin pages is replaced with your site logo.<\/p>\n\n<p><strong>AI crawler policy.<\/strong> The whole market treats AI crawlers as a threat to be\nlocked out. Hafen Core does the opposite: it helps you get found and cited. To\ndo that, it cleanly separates what almost everyone conflates: training (GPTBot,\nClaudeBot, CCBot), search\/index (OAI-SearchBot, Claude-SearchBot,\nPerplexityBot, Googlebot) and live retrieval by a human in a chat\n(ChatGPT-User, Claude-User, Perplexity-User). Blocking training costs NO\nvisibility. Blocking search costs all citability. The interface prevents\nexactly that mistake, with plain-language warnings instead of fine print.\nDefault: nothing blocked. This is not a blocker plugin.<\/p>\n\n<p><strong>AI traffic dashboard, entirely local.<\/strong> Shows which AI bots fetch your\ncontent, which pages they crawl the most, how many visitors come back from AI\nanswers, and the key figure: crawl-to-refer, i.e. how many pages a provider\nfetches before it sends you one visitor. No account, no cloud, no IP addresses\nin the database. If you enable the optional OpenAI bot verification, hits from\nGPTBot &amp; Co. are checked against the official IP ranges; where a provider\npublishes none (Anthropic, Perplexity, Meta), the dashboard says so openly\ninstead of presenting a user agent string as proof.<\/p>\n\n<p><strong>IndexNow.<\/strong> Reports new and changed content immediately to Bing and\nparticipating search engines instead of waiting for the next crawl. Relevant\nbecause ChatGPT's web answers are backed by the Bing index. Off by default\n(opt-in).<\/p>\n\n<p><strong>Markdown for agents.<\/strong> Agentic clients (Claude Code, Cursor, OpenCode)\nrequest pages with \"Accept: text\/markdown\". Hafen Core answers with a clean\nMarkdown version of your content, alternatively via ?format=md or the .md\nsuffix. That saves the model the layout, navigation and script ballast. The\nMarkdown version is sent with \"X-Robots-Tag: noindex\", and \"Vary: Accept\" is\nplaced specifically on the responses that can also be served as Markdown, so\nno page cache serves the Markdown version to browsers \u2013 and on no other\nresponse, so proxy caches do not fragment unnecessarily. Only published,\npublicly visible, non-password-protected content is served.<\/p>\n\n<p><strong>Citability linter in the editor.<\/strong> Checks the post against 15 rules and\nshows, per rule, whether it passes and how well it is supported by evidence\n(strong \/ medium \/ weak), including the source. Deliberately WITHOUT a 0\u2013100\nscore: nobody knows a citation probability, and we do not pretend to. It also\nincludes a check for prompt injection and cloaking, because that is a penalty\nissue, not an optimization issue. The optional AI deep check uses the AI\nassistant and is not a requirement: all rules run without AI as well.<\/p>\n\n<p><strong>Abilities API and WebMCP.<\/strong> Where WordPress ships the Abilities API (6.9+),\nHafen Core registers read-only abilities (page as Markdown, search content) as\nwell as the AI assistant's generators; only the read-only ones are exposed to\nMCP. On top of that come read-only WebMCP browser tools. Honest framing:\nWebMCP is a Chrome experiment and only has an effect while the tab is open.\nCrawlers see none of it; it does nothing for visibility. A tiny snippet loads\nthe script only in browsers that actually have the API; everyone else pays 0\nadditional requests. Both are pure feature detection, not a dependency.<\/p>\n\n<p><strong>llms.txt generator.<\/strong> Publishes a curated content map at \/llms.txt (and\n\/llms-full.txt). Honest framing: Google states that it ignores llms.txt, and\nmeasurements show AI systems practically never fetch the file. Useful for\ncoding agents, not for visibility in AI search. We ship it because it costs\nnothing, and we promise nothing for it.<\/p>\n\n<p><strong>Performance status.<\/strong> Speed is a core commitment of the Hafen family. The\ndashboard (Settings &gt; AI Traffic) therefore shows honestly what your setup\ndelivers: page cache detected or not, compression via self-test, the theme's\nfont mode (variable\/static\/system) \u2013 each with a plain-language\nrecommendation. Plus an option to disable the WordPress emoji script (~26 KB\nand one external request to s.w.org saved; off by default). Cache and\ncompression are server matters no plugin can solve from the inside. That is\nexactly why we display them instead of making promises.<\/p>\n\n<p>Everything runs without a build step and is GDPR-friendly. Schema, blocks and\nllms.txt work entirely locally. External connections only occur for features\nyou explicitly enable or trigger: the optional AI assistant (through the\nWordPress AI client, provider and key configured under Settings &gt; Connectors,\nonly on click), the optional OpenAI bot verification (IP ranges, off by\ndefault), IndexNow (opt-in) and the video block (YouTube, only after a\nclick). Details under \"External services\".<\/p>\n\n<h3>External services<\/h3>\n\n<p>The optional AI assistant generates suggestions (meta description, TL;DR,\nFAQ) from your post content. All requests run through the WordPress AI\nclient (WordPress 7.0+): which provider receives the data, and with which\nkey, is configured centrally under Settings &gt; Connectors. The plugin itself\ndoes not contact any AI provider directly. Data is sent ONLY if you (a)\nenable the assistant under Settings &gt; Hafen Core and (b) click a suggestion\nbutton in the editor; the post's title and text then go to the connector you\nconfigured. The same applies to the optional AI deep check of the citability\nlinter: only if you explicitly tick \"AI deep check\" in the editor and start\nthe check, an excerpt of the post (at most 5,000 characters) is sent to your\nconfigured connector. Without that checkbox the linter runs entirely locally\nand rule-based. On installations without a configured WordPress AI client,\nboth features stay inactive.<\/p>\n\n<p>The \"Hafen Video (2-click)\" block embeds YouTube videos in a\nprivacy-friendly way: before the click, nothing is loaded from YouTube (no\nthumbnail, no request). Only when visitors click the play area is an iframe\nloaded from https:\/\/www.youtube-nocookie.com; at that point data is\ntransmitted to Google. The notice text on the play area informs about this.<\/p>\n\n<p>YouTube terms of service: https:\/\/www.youtube.com\/t\/terms\nGoogle privacy policy: https:\/\/policies.google.com\/privacy<\/p>\n\n<p>IndexNow (Microsoft Bing): if you enable IndexNow under Settings &gt; Hafen Core\n(off by default), the plugin reports the affected URL to\nhttps:\/\/api.indexnow.org\/indexnow when content is published or updated. Sent\nare exclusively: the URL of the public content, your hostname, the locally\ngenerated IndexNow key and the location of the key file. No content, no user\ndata and no visitor data are transmitted. Without this activation nothing is\nsent.<\/p>\n\n<p>IndexNow terms of use: https:\/\/www.indexnow.org\/terms\nMicrosoft privacy statement: https:\/\/privacy.microsoft.com\/privacystatement<\/p>\n\n<p>OpenAI IP ranges (bot verification, opt-in): OFF by default. Only if you\nexplicitly enable the OpenAI bot verification under Settings &gt; AI Traffic\ndoes the plugin fetch the public IP lists https:\/\/openai.com\/gptbot.json,\nhttps:\/\/openai.com\/searchbot.json and https:\/\/openai.com\/chatgpt-user.json\nweekly via cron, to check whether a hit really comes from OpenAI and does not\nmerely fake its user agent. This is a pure download; no data of yours is\ntransmitted in the process. The check itself runs locally. Without this\nactivation not a single fetch is made.<\/p>\n\n<p>OpenAI terms of use: https:\/\/openai.com\/policies\/terms-of-use\nOpenAI privacy policy: https:\/\/openai.com\/policies\/privacy-policy<\/p>\n\n<h3>Privacy<\/h3>\n\n<p>The AI traffic measurement writes to its own table ({prefix}hafen_ai_hits).\nIt stores exclusively: timestamp, bot or source identifier, purpose\n(training, search, live retrieval, referral), the ID of the requested post, a\nhash of the path and a yes\/no verification field.<\/p>\n\n<p>Explicitly NOT stored: IP addresses, user agent strings, cookies, session\nidentifiers or any other personal data. The IP address is only checked in\nmemory against the official provider IP ranges and discarded afterwards.\nLogged-in users are not recorded at all. Retention is limited to 90 days by\ndefault (configurable between 7 and 365 days); a daily cron run deletes older\nentries. No data is transmitted to hafenstudios or third parties.<\/p>\n\n<h3>Copyright<\/h3>\n\n<p>Hafen Core, (C) 2026 hafenstudios.\nHafen Core is distributed under the GNU General Public License v2 or later.<\/p>\n\n<p>All bundled assets are GPL-compatible:<\/p>\n\n<ul>\n<li>assets\/mascot\/captain-*.webp \u2014 brand mascot \"Kapit\u00e4n Ahoi\": original work by\nhafenstudios, created with AI assistance (OpenAI ChatGPT\/DALL\u00b7E). No\nthird-party templates or stock images were used. (C) 2026 hafenstudios,\nreleased under GPLv2 or later.<\/li>\n<li>All icons are inline SVG, an original set, (C) 2026 hafenstudios, GPLv2 or\nlater.<\/li>\n<li>No font files, libraries or third-party assets are bundled.<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload and activate the plugin (Plugins &gt; Add New &gt; Upload).<\/li>\n<li>After activation, \/llms.txt is immediately available and the schema is active.<\/li>\n<li>Under Settings &gt; Hafen Core, adjust the organization name, logo and the\nswitches for schema, llms.txt, traffic measurement and IndexNow.<\/li>\n<li>Under Settings &gt; AI Crawler Policy, define which AI bots are allowed.\nRecommended: \"Do not train, but cite\". Default: everything allowed.<\/li>\n<li>Under Settings &gt; AI Traffic, see who fetches your content and who sends\nvisitors back in return.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"do%20i%20need%20the%20hafen%20theme%3F\"><h3>Do I need the Hafen theme?<\/h3><\/dt>\n<dd><p>No. The blocks, the schema and llms.txt work with any theme. With the Hafen\ntheme they share design tokens and look like one consistent whole.<\/p><\/dd>\n<dt id=\"does%20the%20schema%20collide%20with%20an%20seo%20plugin%3F\"><h3>Does the schema collide with an SEO plugin?<\/h3><\/dt>\n<dd><p>No. In auto mode (default), Hafen Core detects common SEO plugins (Yoast,\nRank Math, SEOPress, All in One SEO, The SEO Framework, Slim SEO, Squirrly)\nand steps back where schema overlaps: it leaves Organization, WebSite, Article\nand Breadcrumb to the SEO plugin and only outputs FAQPage\/HowTo generated from\nthe Hafen answer blocks. The mode can be changed under Settings &gt; Hafen Core\n(Auto \/ Full \/ Answer schema only \/ Off). Fine-grained control via the\nhafen_core_schema_nodes filter.<\/p><\/dd>\n<dt id=\"are%20external%20services%20contacted%3F\"><h3>Are external services contacted?<\/h3><\/dt>\n<dd><p>Schema, llms.txt, crawler policy, Markdown delivery, the citability linter\n(without the deep check) and the traffic dashboard work entirely locally.\nExternal connections only occur for features you explicitly enable: the AI\nassistant including the linter's optional AI deep check (through the\nWordPress AI client and the connector you configured), IndexNow (opt-in),\nthe optional OpenAI bot verification (Settings &gt; AI Traffic; when enabled it\nfetches OpenAI's public IP ranges weekly) and the video block (YouTube, only\nafter a click). Without these consents the plugin makes not a single\nexternal call on its own. Details under \"External services\".<\/p><\/dd>\n<dt id=\"does%20the%20plugin%20block%20ai%20bots%3F\"><h3>Does the plugin block AI bots?<\/h3><\/dt>\n<dd><p>Only if you explicitly configure it to. The default blocks nothing.\nRecommended is \"Do not train, but cite\": turn away training bots, leave\nsearch and retrieval bots open. And the honest limitation right away:\nrobots.txt is a request, not a lock. Whoever ignores it is not stopped by it;\nreal protection requires a WAF or a CDN. Agentic browsers (ChatGPT Agent,\nPerplexity Comet, Claude for Chrome) send no bot token at all and cannot be\naddressed via robots.txt in principle.<\/p><\/dd>\n<dt id=\"does%20google-extended%20prevent%20the%20ai%20overviews%3F\"><h3>Does Google-Extended prevent the AI Overviews?<\/h3><\/dt>\n<dd><p>No, and this is the most widespread misconception in this field.\nGoogle-Extended is purely an opt-out token for Gemini training. The AI\nOverviews draw from the regular Googlebot index.<\/p><\/dd>\n<dt id=\"why%20are%20my%20bot%20numbers%20lower%20than%20in%20my%20server%20logs%3F\"><h3>Why are my bot numbers lower than in my server logs?<\/h3><\/dt>\n<dd><p>Because a full-page cache (WP Rocket, LiteSpeed, W3 Total Cache, WP Super\nCache, Varnish, Nginx FastCGI, Cloudflare APO) serves the finished page\nwithout PHP running. No WordPress plugin sees those hits, not even a\nmu-plugin. The dashboard detects common cache plugins, displays the\nmeasurement quality openly (three states, including \"INCOMPLETE\") and sets up\nthe required user agent exception \u2013 automatically for WP Rocket, otherwise\nwith a ready-made list to paste. The only gap-free method remains analyzing\nthe server access logs; this plugin cannot and does not try to do that.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.0<\/h4>\n\n<p>The WordPress.org release.<\/p>\n\n<ul>\n<li>The AI assistant now runs exclusively through the WordPress AI client\n(Settings &gt; Connectors, WordPress 7.0+). The former bring-your-own-key\npath with direct provider requests has been removed.<\/li>\n<li>English is now the source language: all admin and frontend strings, the\nreadme, and the block metadata. Translations will be provided through\ntranslate.wordpress.org.<\/li>\n<li>Setup wizard no longer replaces an existing static homepage. If one is\nconfigured, it is kept and the wizard says so; switching remains a\ndeliberate step under Settings &gt; Reading.<\/li>\n<li>llms.txt: tags no longer glue words together, leftovers of unregistered\nshortcodes are removed, untitled posts fall back to their URL, and\nllms-full.txt now carries real content sections (up to 800 words per\nentry, filterable via hafen_core_llms_full_words) instead of the same\n24-word excerpts as llms.txt.<\/li>\n<li>robots.txt: the Content-Signal line now joins the existing\n\"User-agent: *\" group instead of opening a second one, which some\nparsers discard.<\/li>\n<li>Schema: no more BreadcrumbList on the front page, where position 1 and\nthe last entry were identical.<\/li>\n<li>AI assistant prompts follow the site language instead of being\nhard-coded German.<\/li>\n<li>New: a review link in the plugin row and a one-time review request\nafter the first recorded AI visit or the first served llms.txt \u2014 one\nlink for everyone, no rating filter.<\/li>\n<li>Third-party admin notices are removed on the plugin's own screens.<\/li>\n<li>The wizard's plugin step now offers only extensions that actually\nresolve in the WordPress.org directory (hafenstudios-ads today;\nothers appear as they are approved).<\/li>\n<\/ul>\n\n<h4>0.9.0<\/h4>\n\n<p>WordPress.org submission: opt-in instead of automatism where it matters.\n* Fix: The weekly fetch of the public OpenAI IP ranges (for bot verification)\n  previously ran automatically as soon as AI traffic measurement was active\n  (default: on) \u2013 an external call without explicit consent. New switch\n  \"OpenAI bot verification\" under Settings &gt; AI Traffic, OFF by default. The\n  associated cron is only registered while the switch is active and is\n  cleanly removed when it is turned off.\n* New: The logo plate in the access gate now derives its color from the logo\n  instead of hard-coding white (F10). Opaque near-white logos (e.g.\n  Canva\/Office exports with a background like #F5F5F1) previously produced a\n  visible edge on the white plate. The color is sampled once per logo and\n  cached; the fallback remains white (no image access possible or the logo is\n  transparent). Filterable via hafen_core_gate_logo_plate_color.\n* Updated: The AI assistant's model list (Claude Opus 5, Claude Sonnet 5,\n  Claude Haiku 4.5); the default is now the lowest-cost model (Haiku 4.5)\n  instead of the most expensive one, so a freshly enabled assistant does not\n  cause high costs unasked.\n* Cleanup: The remaining inline  outputs (login logo, access gate,\n  accent color\/footer credit in the frontend) now go through\n  wp_add_inline_style() instead of a hand-built  tag; the access gate\n  page loads its CSS from assets\/gate.css. Table names in the plugin's own\n  $wpdb queries are now bound via %i instead of interpolated.\n* Display name shortened; slug and text domain (hafen-core) unchanged.\n* New: languages\/hafen-core.pot regenerated.<\/p>\n\n<h4>0.8.1<\/h4>\n\n<p>Security fix: the access gate only applied to normal page views. Everything\nWordPress serves through other routes remained reachable unprotected, even\nthough the actual page correctly showed the under-construction page with\nHTTP 503.\n* Fix: The REST API (e.g. \/wp-json\/wp\/v2\/pages) served the full content of\n  gated pages unchanged. A new latch using REST's own authentication signal\n  now rejects REST requests with HTTP 503 while the access gate is active and\n  the visitor has not yet passed it. Logged-in users and visitors with a\n  valid access cookie are exempt, so nothing breaks in normal operation.\n* Fix: llms.txt\/llms-full.txt as well as the optional IndexNow key file ran\n  ahead of the access gate in execution order and were therefore served\n  before it could take effect. The access gate now checks first of all.\n* Fix: The Markdown delivery for AI agents (Accept: text\/markdown,\n  ?format=md, .md suffix) had the same flaw for the same reason and served\n  the complete page content despite the active access gate.\n* Fix: \/wp-json\/wp\/v2\/users (and the plain ?rest_route= variant) exposed\n  usernames. This route now stays closed additionally, even for visitors\n  with a valid access cookie, while the access gate is active.\n* New: Emergency off switch for the access gate, independent of the stored\n  setting \u2013 constant HAFEN_CORE_GATE_DISABLED in wp-config.php or filter\n  hafen_core_gate_disabled.\n* Checked and unchanged: normal pages, RSS\/Atom feeds, robots.txt,\n  wp-sitemap.xml and the classic ?author=1 redirect were already correctly\n  gated (they run only AFTER the branch point where the access gate ends the\n  request).<\/p>\n\n<h4>0.8.0<\/h4>\n\n<p>First impressions: no more error message, no empty pages, no bare\n\"No data yet.\" lines.\n* Fix: The assistant step \"Recommended extensions\" offered plugins that do\n  not yet exist in the WordPress.org directory. The result was the same for\n  every user: click, error message. The assistant now queries the directory\n  first (response cached for 12 hours) and only shows what can actually be\n  installed. If nothing is available, the step is skipped entirely; progress\n  bar and step counter adjust automatically.\n* Improvement: The starter pages are now built from the theme's real\n  patterns. \"Contact\" previously got a bare heading and nothing else; now it\n  contains the complete contact section with address, phone, e-mail and\n  opening hours. The markup is inserted inline, not as a pattern reference:\n  that way it can be edited normally in the editor and survives a theme\n  switch.\n* Improvement: The empty states in the AI traffic dashboard now explain what\n  is measured, name a realistic time horizon and say that an empty report is\n  normal for new sites. Previously the page showed \"No data yet.\" three times\n  in a row.\n* Improvement: The reporting period (30 days) is now stated in the headings.\n  Without it, no number on the page could be put into context.\n* Improvement: New shared admin styles (assets\/admin-tokens.css) group the\n  sections into cards. They style exclusively the plugin's own Hafen classes,\n  without overriding WordPress core elements.\n* languages\/hafen-core.pot regenerated: the strings from the access gate\n  (class-access-gate.php) and the login logo (class-login-logo.php) had not\n  been extracted before and were therefore not translatable.<\/p>\n\n<h4>0.7.2<\/h4>\n\n<p>Performance package (together with Hafen theme 0.3.1: variable font and\nsystem font variation \"Stapellauf\").\n* New: Performance status in the AI traffic dashboard. Shows honestly what\n  the setup delivers: page cache detected\/not detected, compression via\n  self-test (gzip\/Brotli, result cached for 12 h, never runs in the\n  frontend) and the active theme's font mode (variable\/static\/system). With\n  a plain-language recommendation per item, because cache and compression\n  are server matters no plugin can solve from the inside.\n* New: Option \"Disable WordPress emoji script\" (Settings &gt; Hafen Core &gt;\n  Performance, also via REST). Saves ~26 KB and the external request to\n  s.w.org. OFF by default, so WordPress behaves as usual.\n* Performance: webmcp.js is no longer loaded unconditionally. An inline\n  snippet (under 300 bytes) loads the script only in browsers that actually\n  have the WebMCP API. For everyone else: 0 additional requests.\n* Fix: The \"Vary: Accept\" header is now only sent on responses that can also\n  serve the same URL as Markdown (servable single views) instead of on every\n  frontend response. Vary on everything fragments LiteSpeed\/proxy caches\n  with no benefit. At the same time, moved from the too-early send_headers\n  hook to template_redirect (priority 0).<\/p>\n\n<h4>0.7.1<\/h4>\n\n<ul>\n<li>Access gate polish: the logo now sits on a white \"plate\" (which also makes\nlogos without a transparent background look right on dark templates), a\ngentle fade-in animation (respects prefers-reduced-motion), a wave\nsilhouette at the page footer, focus ring and button glow in the accent\ncolor, a shake animation on a wrong password. The dark template's second\nbackground glow now follows the accent color instead of fixed indigo.<\/li>\n<\/ul>\n\n<h4>0.7.0<\/h4>\n\n<ul>\n<li>New: Access gate (Under Construction). Protects the whole website with a\npassword and shows visitors one of three bundled templates (Helle Werft,\nNachtfahrt, Horizont) \u2013 with your site logo, site name and your accent\ncolor, without an external password protection plugin. Logged-in users see\nthe website normally; visitors with the password receive a cookie (3 days,\nfilter <code>hafen_core_gate_cookie_days<\/code>). The password is stored only as a\nhash, honeypot + rate limit against brute-forcing, the gate page sends\nHTTP 503 + Retry-After + noindex (safe for SEO). Settings &gt; Hafen Core,\nincluding an admin preview link.<\/li>\n<\/ul>\n\n<h4>0.6.1<\/h4>\n\n<ul>\n<li>New: Login logo. If a site logo is set (Appearance &gt; Site Logo), it\nreplaces the WordPress logo on wp-login.php and on the login page of the\n\"Password Protected\" plugin; the logo links to the homepage instead of\nwordpress.org. Without a logo set, nothing changes. Can be disabled via\nthe <code>hafen_core_login_logo<\/code> filter.<\/li>\n<\/ul>\n\n<h4>0.6.0<\/h4>\n\n<p>The core of this release: we help you get found and cited instead of locking\nAI crawlers out. Without invented numbers, with clearly named limitations.<\/p>\n\n<ul>\n<li>New: AI crawler policy (Settings &gt; AI Crawler Policy). All relevant bots,\ngrouped by purpose: training, search\/index, live retrieval by users. One\nswitch each, default \"everything allowed\". Two presets: \"Maximum\nvisibility\" and \"Do not train, but cite\" (recommended). Output via the\nrobots_txt filter. Anyone who wants to block a search or retrieval bot is\ntold in plain language beforehand what that destroys. An existing physical\nrobots.txt is detected and reported openly, because the filter does not\napply then.<\/li>\n<li>New: AI traffic dashboard (Settings &gt; AI Traffic), 100% local, no account.\nHits by bot and purpose, most-crawled content, visitors from AI answers\n(referrer and utm_source=chatgpt.com) and the crawl-to-refer ratio per\nprovider, put into context with the known industry figures. Coupled to the\npolicy: if a blocked search bot has zero hits, the dashboard says exactly\nthat instead of leaving you guessing.<\/li>\n<li>New: Bot verification against spoofing. Hits from OpenAI are checked\nagainst the official IP ranges (fetched weekly via cron, cached locally),\nGooglebot and Applebot optionally via reverse DNS with forward\nconfirmation. Where a provider publishes nothing (Anthropic, Perplexity,\nMeta), it openly says \"not verifiable\". A user agent string is not proof.<\/li>\n<li>New: Honest measurement quality indicator. With a full-page cache PHP does\nnot run, and no plugin sees the bot hits. The dashboard detects WP Rocket,\nLiteSpeed, W3 Total Cache, WP Super Cache and Cloudflare, names the state\n(complete \/ complete with exception \/ INCOMPLETE) and sets up the user\nagent exception: automatically for WP Rocket via the\nrocket_cache_reject_ua filter, otherwise with a ready-made list to paste.<\/li>\n<li>New: IndexNow (opt-in). Reports new and changed content immediately to\nBing and participating search engines, with a locally generated key at\n\/{key}.txt, debounce against ping floods and a status display of the last\nping.<\/li>\n<li>Privacy: own table {prefix}hafen_ai_hits without IP addresses and without\npersonal data, retention 90 days by default, daily cleanup via cron. See\nthe \"Privacy\" section.<\/li>\n<li>New: Markdown delivery for agents (content negotiation via\n\"Accept: text\/markdown\", ?format=md and the .md suffix). Own HTML-to-\nMarkdown converter without Composer; the Hafen blocks are rendered\nsemantically, not via the HTML detour. \"Vary: Accept\" is sent on every\nresponse so a page cache does not serve the Markdown version to browsers;\nthe Markdown response itself is sent with \"X-Robots-Tag: noindex\". Only\npublished, publicly visible, non-password-protected content is served.<\/li>\n<li>New: Citability linter in the editor. 15 rules, each with evidence\nstrength (strong \/ medium \/ weak) and source, explicitly WITHOUT a 0\u2013100\nscore. Includes a check for prompt injection and cloaking. The AI deep\ncheck for the two rules that are fuzzy under pure rules is optional and\nnot a requirement.<\/li>\n<li>New: Abilities API (WordPress 6.9+, pure feature detection): read-only\nabilities (page as Markdown, search content) plus the AI assistant's\ngenerators. Only the read-only ones are exposed to MCP.<\/li>\n<li>New: WebMCP browser tools, strictly read-only (the contact form is at most\nprefilled, never submitted). Honestly framed: a Chrome experiment, only\neffective while the tab is open, does nothing for visibility.<\/li>\n<li>Honesty instead of marketing: llms.txt is now correctly framed in the\ninterface (speculative standard, ignored by Google according to Google\nitself, practically never fetched, useful for coding agents). The feature\nstays; only the promise is dropped.<\/li>\n<li>Correction: \/llms.txt could include password-protected posts along with an\nexcerpt of the raw content. They are now excluded.<\/li>\n<\/ul>\n\n<h4>0.5.1<\/h4>\n\n<p>WordPress.org preparation.\n* The footer credit is now true opt-in (guideline 10): the checkbox in the\n  assistant is no longer pre-checked, the option's default value is \"hide\".\n  The credit paragraph in the theme footer is hidden via CSS and only shown\n  after explicit consent.\n* Showcase opt-in: honest notice text. The setting is only stored locally,\n  no data is transmitted (there is currently no receiving backend).\n* Origin of the mascot artwork disclosed in the copyright section (original\n  work by hafenstudios, created with AI assistance).\n* Escaping: the SEO plugin notice now uses wp_kses_post( sprintf( ... ) )\n  instead of sprintf( esc_html__( ... ) ).\n* Cleanup: load_plugin_textdomain() removed (unnecessary for plugins from\n  the .org directory since WordPress 4.6); the superfluous jQuery dependency\n  of wizard.js is gone (the script only uses fetch and DOM APIs).\n* New: languages\/hafen-core.pot.<\/p>\n\n<h4>0.5.0<\/h4>\n\n<p>Source of this release: hands-on feedback from the real-world project\nvielfalt-begleiten.nrw.<\/p>\n\n<ul>\n<li>Assistant: free accent color via color picker and hex field in addition to\nthe six presets (F1). The color is now also written into the user global\nstyles (complete brand palette including brand-dark, brand-light and\ngradient) so it applies in the block and site editor too, not only in the\nfrontend. The inline CSS remains as a fallback with identical values.<\/li>\n<li>Assistant: the contact page is now preselected in the starter pages step,\nlike the homepage and blog (F2).<\/li>\n<li>Showcase reminder: a discreet, dismissible admin notice at the earliest 14\ndays after setup and only from three published pages onward, instead of\nonly the (too early) question directly in the assistant (F3).<\/li>\n<li>New block \"Hafen Video (2-click)\": privacy-friendly YouTube embed via\nyoutube-nocookie.com. Before the click only a brand-colored area with a\nplay symbol and notice text, no external request.<\/li>\n<li>Robustness: protection against wptexturize damage to inline scripts in\ntemplate parts (\"&amp;&amp;\" became \"&#038;&#038;\", SyntaxError in the frontend).\nScript segments are masked during part rendering and restored unchanged\nafterwards; wptexturize stays globally active (F6).<\/li>\n<li>REST: the settings (schema_mode, enable_llms_txt, organization_name,\norganization_logo) and the accent color are now readable and writable via\n\/wp-json\/wp\/v2\/settings (F9).<\/li>\n<\/ul>\n\n<h4>0.4.1<\/h4>\n\n<ul>\n<li>Final brand mascot (Captain \"Ahoi\"): replaces the placeholder SVG with\nreal artwork, with its own pose per assistant step (welcome, extensions,\nbrand, starter pages, done) and in the welcome notice.<\/li>\n<li>Correction: real umlauts (\u00e4\/\u00f6\/\u00fc\/\u00df) throughout instead of ASCII\nsubstitutes in all visible texts, block descriptions and AI prompts.<\/li>\n<\/ul>\n\n<h4>0.4.0<\/h4>\n\n<ul>\n<li>AI assistant (bring your own key): generates suggestions for meta\ndescription, TL;DR and FAQ from the post content in the editor. Uses your\nown Anthropic key, requests go directly to Anthropic (no middleman).\nSelectable model (default Claude Opus 4.8). Off by default, opt-in.<\/li>\n<\/ul>\n\n<h4>0.3.0<\/h4>\n\n<ul>\n<li>Setup assistant (onboarding): guides you after activation through\nrecommended extensions (opt-in, WordPress.org), brand (logo + accent color\ncolors the theme), starter pages and completion. Dismissible welcome\nnotice, no obligation. With the brand mascot (captain) as companion\n(placeholder artwork).<\/li>\n<li>The accent color is applied live to the theme via a :root variable.<\/li>\n<li>Footer credit (\"Built with Hafen\") can be shown\/hidden via the assistant.<\/li>\n<\/ul>\n\n<h4>0.2.0<\/h4>\n\n<ul>\n<li>SEO plugin coexistence: detects common SEO plugins (Yoast, Rank Math,\nSEOPress, AIOSEO, The SEO Framework, Slim SEO, Squirrly) and automatically\nsteps back where schema overlaps. New schema mode (Auto\/Full\/Answer\nonly\/Off) replaces the simple on-off switch.<\/li>\n<\/ul>\n\n<h4>0.1.0<\/h4>\n\n<ul>\n<li>Schema engine (Organization, WebSite, Article, BreadcrumbList, FAQPage,\nHowTo).<\/li>\n<li>Answer engine blocks: FAQ, HowTo, TL;DR, Definition (server-rendered, no\nbuild).<\/li>\n<li>llms.txt \/ llms-full.txt generator with rewrite endpoint.<\/li>\n<li>Settings page for organization, schema and llms.txt switches.<\/li>\n<\/ul>","raw_excerpt":"The companion plugin for the Hafen theme. JSON-LD schema, answer blocks, AI crawler policy, local AI traffic stats, Markdown delivery and llms.txt.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/cn.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/359531","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cn.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/cn.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/cn.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=359531"}],"author":[{"embeddable":true,"href":"https:\/\/cn.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/hafenstudios"}],"wp:attachment":[{"href":"https:\/\/cn.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=359531"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/cn.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=359531"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/cn.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=359531"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/cn.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=359531"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/cn.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=359531"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/cn.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=359531"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}