{"id":332969,"date":"2026-08-19T13:06:49","date_gmt":"2026-08-19T13:06:49","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/consentkit\/"},"modified":"2026-08-19T13:49:58","modified_gmt":"2026-08-19T13:49:58","slug":"biscotto-cookie-consent","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/biscotto-cookie-consent\/","author":23524234,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.5.5","stable_tag":"1.5.5","tested":"7.0.4","requires":"5.9","requires_php":"7.4","requires_plugins":null,"header_name":"Biscotto \u2013 Cookie Consent","header_author":"Food & Tech","header_description":"GDPR\/ePrivacy cookie consent compliant with the Italian DPA (Garante) guidelines: Google Consent Mode v2, GTM and LinkedIn. No page or CPT limits.","assets_banners_color":"4d79e7","last_updated":"2026-08-19 13:49:58","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/github.com\/renatoromano-png\/Biscotto-Cookie-Consent","header_author_uri":"https:\/\/github.com\/renatoromano-png","rating":0,"author_block_rating":0,"active_installs":0,"downloads":64,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.5.4":{"tag":"1.5.4","author":"renatosaka","date":"2026-08-19 13:06:12"},"1.5.5":{"tag":"1.5.5","author":"renatosaka","date":"2026-08-19 13:49:58"}},"upgrade_notice":{"1.5.4":"<p>Internal scanner refactor only; no action required and no functional change.<\/p>","1.5.3":"<p>Breaking: plugin, slug and JavaScript API renamed. Settings and consent-log records are NOT migrated - reconfigure them. Shortcodes are now [biscotto_cookie_table], [biscotto_consent_settings], [biscotto_cookie_policy]; blocked scripts must use data-biscotto-category. Visitors must consent again.<\/p>","1.5.0":"<p>Renamed to &quot;Biscotto&quot;. Internal cleanups for WordPress.org guideline compliance.<\/p>","1.4.0":"<p>Scan tab gains database-enrichment and update-check buttons; Cookies tab gains a one-click &quot;copy shortcode&quot; box for your cookie policy page.<\/p>","1.2.0":"<p>New banner position &quot;Bottom-right box&quot;: a compact card on desktop, full-width bar on mobile.<\/p>","1.1.1":"<p>Scan tab: load the URLs to scan from the site sitemap, with clearer guidance.<\/p>","1.1.0":"<p>Adds a runtime cookie scanner to detect cookies and third-party services loaded on your pages.<\/p>","1.0.0":"<p>First public release.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3654647,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3654647,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3654647,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3654647,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.5.4","1.5.5"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3654647,"resolution":"1","location":"assets","locale":"","width":1916,"height":1029},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3654647,"resolution":"2","location":"assets","locale":"","width":1896,"height":1029},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3654647,"resolution":"3","location":"assets","locale":"","width":1919,"height":1029},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3654647,"resolution":"4","location":"assets","locale":"","width":1914,"height":1030},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3654647,"resolution":"5","location":"assets","locale":"","width":1917,"height":1033}},"screenshots":{"1":"Compliant consent banner (bottom bar).","2":"Granular per-category preferences panel.","3":"Settings &rarr; General: texts, color, re-prompt.","4":"Settings &rarr; Cookies: cookie registry.","5":"Settings &rarr; Integrations: Consent Mode v2, GTM, LinkedIn."}},"plugin_section":[],"plugin_tags":[20011,223629,388,20272,131785],"plugin_category":[],"plugin_contributors":[276504],"plugin_business_model":[],"class_list":["post-332969","plugin","type-plugin","status-publish","hentry","plugin_tags-consent","plugin_tags-consent-mode","plugin_tags-cookie","plugin_tags-cookie-banner","plugin_tags-gdpr","plugin_contributors-renatosaka","plugin_committers-renatosaka"],"banners":{"banner":"https:\/\/ps.w.org\/biscotto-cookie-consent\/assets\/banner-772x250.png?rev=3654647","banner_2x":"https:\/\/ps.w.org\/biscotto-cookie-consent\/assets\/banner-1544x500.png?rev=3654647","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/biscotto-cookie-consent\/assets\/icon-128x128.png?rev=3654647","icon_2x":"https:\/\/ps.w.org\/biscotto-cookie-consent\/assets\/icon-256x256.png?rev=3654647","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/biscotto-cookie-consent\/assets\/screenshot-1.png?rev=3654647","caption":"Compliant consent banner (bottom bar)."},{"src":"https:\/\/ps.w.org\/biscotto-cookie-consent\/assets\/screenshot-2.png?rev=3654647","caption":"Granular per-category preferences panel."},{"src":"https:\/\/ps.w.org\/biscotto-cookie-consent\/assets\/screenshot-3.png?rev=3654647","caption":"Settings &rarr; General: texts, color, re-prompt."},{"src":"https:\/\/ps.w.org\/biscotto-cookie-consent\/assets\/screenshot-4.png?rev=3654647","caption":"Settings &rarr; Cookies: cookie registry."},{"src":"https:\/\/ps.w.org\/biscotto-cookie-consent\/assets\/screenshot-5.png?rev=3654647","caption":"Settings &rarr; Integrations: Consent Mode v2, GTM, LinkedIn."}],"raw_content":"<!--section=description-->\n<p>Biscotto is an open-source cookie consent manager with no artificial limits (no caps on pageviews, pages or Custom Post Types).<\/p>\n\n<p>Features:<\/p>\n\n<ul>\n<li>Compliant consent banner: close (X) button, equal Accept\/Reject buttons, link to the privacy notice, granular preferences.<\/li>\n<li>Prior blocking of scripts (<code>type=\"text\/plain\"<\/code> + <code>data-biscotto-category<\/code>) until consent is given.<\/li>\n<li>Google Consent Mode v2 (default denied before GTM, update on consent).<\/li>\n<li>Google Tag Manager via dataLayer.<\/li>\n<li>LinkedIn Insight Tag loaded only with marketing consent.<\/li>\n<li>Compliant banner re-prompt (minimum 6 months) and re-consent when the cookie policy changes.<\/li>\n<li>Optional pseudonymized consent log for GDPR audits.<\/li>\n<li>Runtime cookie scanner: loads your pages in a hidden iframe (admin only) and detects the cookies and third-party domains actually loaded, then suggests registry entries to review and save.<\/li>\n<li>Cookie database enrichment: fills in missing service, category, retention period and privacy-policy link using a bundled copy of Open Cookie Database (Apache-2.0), with an optional manual check for dataset updates.<\/li>\n<li>One-click \"copy code\" box for building your cookie policy page from the plugin's shortcode.<\/li>\n<\/ul>\n\n<p>The core is a dependency-free JavaScript engine, reusable on non-WordPress sites too.<\/p>\n\n<p>Cookies are managed through a pre-filled registry of the most common services, editable by hand from the admin and extendable with the built-in scanner.<\/p>\n\n<p>Roadmap (in progress):<\/p>\n\n<ul>\n<li>Automatic blocking of iframes and embeds (Google Maps, YouTube) and Google Fonts with a \"click to load\" placeholder.<\/li>\n<\/ul>\n\n<h3>External services<\/h3>\n\n<p>This plugin can connect to the third-party services listed below. They are all optional and disabled by default: the plugin does not contact them unless you enable the related feature or, for the update check, explicitly click the button.<\/p>\n\n<h4>Google Tag Manager<\/h4>\n\n<p>If you enable the \"Google Tag Manager\" integration and enter a container ID (Settings &rarr; Biscotto &rarr; Integrations), the plugin loads the GTM library from https:\/\/www.googletagmanager.com\/gtm.js. GTM then runs the tags you configured in your own Google Tag Manager account. Thanks to Google Consent Mode v2 the storage is set to \"denied\" by default, so visitor data (such as IP address and cookies) is sent to Google only after the visitor consents. Service provided by Google LLC.\nTerms of service: https:\/\/marketingplatform.google.com\/about\/analytics\/tag-manager\/use-policy\/\nPrivacy policy: https:\/\/policies.google.com\/privacy<\/p>\n\n<h4>LinkedIn Insight Tag<\/h4>\n\n<p>If you enable the \"LinkedIn\" integration and enter a Partner ID (Settings &rarr; Biscotto &rarr; Integrations), the plugin loads the LinkedIn Insight Tag from https:\/\/snap.licdn.com\/li.lms-analytics\/insight.min.js and sends analytics\/conversion data to LinkedIn \u2014 but only after the visitor grants \"marketing\" consent. Service provided by LinkedIn Corporation (Microsoft).\nTerms of service: https:\/\/www.linkedin.com\/legal\/l\/service-terms\nPrivacy policy: https:\/\/www.linkedin.com\/legal\/privacy-policy<\/p>\n\n<h4>GitHub API (cookie-database update check)<\/h4>\n\n<p>Only when an administrator clicks \"Check for database updates\" (Settings &rarr; Biscotto &rarr; Scan), the plugin makes a single GET request to the public GitHub API at https:\/\/api.github.com\/ to read the date of the latest commit that changed the bundled Open Cookie Database file. No personal data and no site data are sent \u2014 only the request for a public commit date \u2014 and the result is cached for 24 hours. There are no automatic or background calls. Service provided by GitHub, Inc. (Microsoft).\nTerms of service: https:\/\/docs.github.com\/site-policy\/github-terms\/github-terms-of-service\nPrivacy policy: https:\/\/docs.github.com\/site-policy\/privacy-policies\/github-general-privacy-statement<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>biscotto-cookie-consent<\/code> folder to <code>\/wp-content\/plugins\/<\/code>.<\/li>\n<li>Activate the plugin from the Plugins menu.<\/li>\n<li>Go to Settings &rarr; Biscotto and configure texts, cookies and integrations.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20it%20work%20with%20custom%20post%20types%3F\"><h3>Does it work with Custom Post Types?<\/h3><\/dt>\n<dd><p>Yes, with no extra configuration and no limits.<\/p><\/dd>\n<dt id=\"is%20it%20compliant%20with%20the%20italian%20data%20protection%20authority%20%28garante%29%3F\"><h3>Is it compliant with the Italian Data Protection Authority (Garante)?<\/h3><\/dt>\n<dd><p>The plugin implements the technical requirements of the 10 June 2021 guidelines. Overall compliance also depends on a correct privacy notice and on the proper classification of each site's cookies.<\/p><\/dd>\n<dt id=\"does%20it%20send%20data%20to%20external%20services%3F\"><h3>Does it send data to external services?<\/h3><\/dt>\n<dd><p>Yes, in the specific cases described under \"External services\" above, and always under your control. In short: the Google (Consent Mode\/GTM) and LinkedIn scripts load only if you configure them and only after consent; the \"Check for database updates\" button contacts the public GitHub API only when you click it, sending no personal or site data. Everything else stays local \u2014 Biscotto does not otherwise communicate with any third-party server \u2014 and the optional consent log stays pseudonymized in your site's database.<\/p><\/dd>\n<dt id=\"how%20is%20the%20optional%20consent%20log%20protected%20from%20abuse%3F\"><h3>How is the optional consent log protected from abuse?<\/h3><\/dt>\n<dd><p>The log is disabled by default, and while it is disabled the REST route is not registered at all. When enabled, the route is public by necessity \u2014 anonymous visitors record their own consent through it via <code>navigator.sendBeacon<\/code>, so there is no user to authorise \u2014 but writes are bounded by limits that do not depend on the nonce. Each address is allowed 10 writes per hour. Independently of that, the plugin counts the rows already written in the past hour immediately before inserting and refuses beyond a site-wide ceiling, so rejected requests cannot consume the quota; the ceiling can be adjusted with the <code>biscotto_write_ceiling<\/code> filter. Identical submissions from the same visitor write nothing for up to 24 hours (the visitor identifier is salted per day, so the effective de-duplication window is shorter for submissions made near midnight UTC), and records older than the configured retention period (12 months by default) are deleted daily.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.5.5<\/h4>\n\n<ul>\n<li>New: \"Create Cookie Policy page\" button (Cookies tab) generates a draft WordPress page pre-filled with a GDPR\/Garante-oriented cookie policy template and the <code>[biscotto_cookie_policy]<\/code> shortcode already in place, so the automatically detected cookie list appears in the page. The draft is never auto-published: it is clearly marked as needing the site owner's own details before publishing, and clicking again opens the existing draft instead of creating duplicates.<\/li>\n<li>New: <code>[biscotto_last_updated]<\/code> shortcode shows the policy's \"last updated\" date, backed by a stored option and bumped on demand from the new \"Update last-modified date\" button, instead of freezing a date as static text.<\/li>\n<\/ul>\n\n<h4>1.5.4<\/h4>\n\n<ul>\n<li>Internal: the scanner's host and cookie classification tables no longer store the vendor's public privacy-policy link inline next to each hostname; the link is now resolved from a separate service-name lookup. No functional change \u2014 the scanner still only matches hostnames found in the site's own markup and never contacts them.<\/li>\n<\/ul>\n\n<h4>1.5.3<\/h4>\n\n<ul>\n<li>Plugin renamed to \"Biscotto \u2013 Cookie Consent\"; slug and text domain are now <code>biscotto-cookie-consent<\/code>.<\/li>\n<li>Internal PHP layer renamed to Biscotto (classes, constants, option, log table, REST namespace). Existing installations must be reconfigured.<\/li>\n<li>Consent log endpoint hardened: the <code>\/log<\/code> REST route is registered only when the consent log is enabled; writes are limited by a per-visitor-IP rate limit and by a site-wide ceiling on rows written per hour (adjustable via the <code>biscotto_write_ceiling<\/code> filter), with 24-hour de-duplication per visitor.<\/li>\n<li>New: automatic retention for consent log records, with a configurable retention period (default 12 months).<\/li>\n<\/ul>\n\n<h4>1.5.0<\/h4>\n\n<ul>\n<li>Plugin renamed to \"Biscotto \u2013 Cookie Consent &amp; Consent Mode\"; the text domain is now <code>biscotto<\/code>.<\/li>\n<li>Compliance: the Consent Mode v2 default and the Google Tag Manager loader are now added with <code>wp_add_inline_script()<\/code> on enqueued handles instead of being printed inline; the cookie-registry admin behaviour moved to <code>admin\/js\/cookies.js<\/code>, enqueued with <code>wp_enqueue_script()<\/code>.<\/li>\n<li>Docs: added an \"External services\" section documenting Google Tag Manager, the LinkedIn Insight Tag and the on-demand GitHub update check (what is sent, when, and links to each service's terms and privacy policy).<\/li>\n<\/ul>\n\n<h4>1.4.0<\/h4>\n\n<ul>\n<li>New: \"Enrich from database\" button (Scan tab) fills in missing service, category, retention period and privacy-policy link for scan suggestions using a bundled copy of Open Cookie Database (Apache-2.0, no external calls). Never overwrites a field you already set.<\/li>\n<li>New: \"Check for database updates\" button (Scan tab) checks, only when you click it, whether a newer snapshot of Open Cookie Database is available upstream on GitHub. No automatic checks, no site data sent.<\/li>\n<li>New: \"Copy code\" box (Cookies tab) with the <code>[biscotto_cookie_policy]<\/code> shortcode ready to paste into your cookie policy page.<\/li>\n<\/ul>\n\n<h4>1.3.3<\/h4>\n\n<ul>\n<li>Fixed: mobile action buttons now share equal width regardless of label length; \"Manage preferences\" moved to its own centered row below Accept\/Reject. Landscape phones: reduced typography\/padding so the banner fits in about half the screen instead of overflowing.<\/li>\n<\/ul>\n\n<h4>1.3.2<\/h4>\n\n<ul>\n<li>Fixed: primary\/link buttons now resist being restyled by the host theme (explicit color\/background\/border rules) so the accent color and auto-contrast text always render correctly regardless of theme CSS.<\/li>\n<\/ul>\n\n<h4>1.3.1<\/h4>\n\n<ul>\n<li>Fixed: mobile banner text and buttons now actually scale up on the \"Bottom bar\" position (fixed a CSS specificity issue where base rules were overriding the compact-mode typography).<\/li>\n<\/ul>\n\n<h4>1.3.0<\/h4>\n\n<ul>\n<li>New: banner position \"Bottom-left box\", mirroring \"Bottom-right box\".<\/li>\n<li>Improved: responsive banner behaviour is now driven by width\/orientation\/height instead of special cases \u2014 compact full-width bar on phones (any orientation) and portrait tablets, unchanged desktop appearance otherwise.<\/li>\n<li>New: automatic text contrast (WCAG relative luminance) when background\/accent colors are customized and the text-color fields are left empty.<\/li>\n<\/ul>\n\n<h4>1.2.4<\/h4>\n\n<ul>\n<li>Fixed: on the \"Bottom bar\" position the enlarged title and body text were overridden by base rules (equal CSS specificity); the banner box grew but the fonts stayed small. Typography now uses a higher-specificity selector and renders large as intended.<\/li>\n<\/ul>\n\n<h4>1.2.3<\/h4>\n\n<ul>\n<li>Improved: the \"Bottom bar\" banner position is now a full-width band about half the screen tall, with large readable text and buttons that scale with the viewport. More prominent, Complianz-style presence. Desktop keeps sensible size caps.<\/li>\n<\/ul>\n\n<h4>1.2.2<\/h4>\n\n<ul>\n<li>Improved: banner text on smartphones enlarged further for readability (body 19px, title 23px, links 16px). Desktop appearance unchanged.<\/li>\n<\/ul>\n\n<h4>1.2.1<\/h4>\n\n<ul>\n<li>Improved: larger, more legible banner text on smartphones (body 14&rarr;17px, title 16&rarr;20px, links 13&rarr;15px, bigger tap targets on buttons). Desktop appearance unchanged.<\/li>\n<\/ul>\n\n<h4>1.2.0<\/h4>\n\n<ul>\n<li>New: banner position \"Bottom-right box\". On desktop the banner shows as a compact card anchored to the bottom-right corner instead of a full-width bar; on mobile it falls back to a full-width bottom bar for easy tapping. Selectable under Settings &rarr; General &rarr; Banner position.<\/li>\n<\/ul>\n\n<h4>1.1.1<\/h4>\n\n<ul>\n<li>Scan tab: \"Load from sitemap\" button populates the URL list from the site sitemap (wp-sitemap.xml \/ sitemap_index.xml), with REST fallback. Only same-origin URLs are added.<\/li>\n<li>Clearer help text: the scanner checks only the listed URLs (not the whole site); the homepage already covers site-wide scripts.<\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>New: runtime cookie scanner (Scan tab). Loads target pages in a hidden, admin-only iframe with consent forced to \"accepted\", reads cookies, storage and third-party resource domains, and suggests registry entries to review and import.<\/li>\n<li>Internal classifier mapping common domains and cookie names to service and category. No external calls and no third-party data bundled.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>First release: banner, granular preferences, Consent Mode v2, GTM, LinkedIn, prior blocking, optional log.<\/li>\n<\/ul>","raw_excerpt":"GDPR\/ePrivacy cookie consent compliant with the Italian DPA (Garante) guidelines: Google Consent Mode v2, GTM and LinkedIn. No page or CPT limits.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/332969","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=332969"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/renatosaka"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=332969"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=332969"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=332969"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=332969"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=332969"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=332969"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}