Security News
tea.xyz Spam Plagues npm and RubyGems Package Registries
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
just-good-cookies
Advanced tools
Readme
Please note: JGC is in its pre-release stage It may be buggy and may not work as expected. Some features may be added, others may be completely removed or delayed. ๐ง It is currently being actively tested. Use at your own risk! ๐ง
Just Good Cookies (JGC) is a simple (but delicious) cookie consent solution made in vanilla JavaScript. It is designed to be fast, painless and easy to use. JGC supports both automatic and manual cookie blocking modes, and also generates a fully automatic settings panel.
This library provides 9 different banner styles that ONLY work in conjunction with TailwindCSS โค๏ธ (which is not included in the package, so you can decide for yourself how to integrate it, see below).
JFC is a free open-source project that I work on in my spare time (but hey, I put a lot of work into it).
If you want to support the project, you can buy me a coffee or a beer (or two ๐ป, I love beer) โค๏ธ!
Thank you!
There are 2 ways to use JGC in your projects:
<script src="https://cdn.jsdelivr.net/gh/francescomugnai/just-good-cookies@0.9.9/dist/justgoodcookies.min.js"></script>
Install Tailwind (if you haven't already, see below)
Initialize JGC
<script>
justgoodcookies.init({
locale: "it", // ISO 639-1 language code
layout: "style1",
privacyLink: "https://www.mysite.com/privacy-policy/",
cookies: {
necessary: { // this is mandatory
title: "Necessary cookies",
description: "Some text to describe them",
},
},
});
</script>
And...you are done ๐
npm install just-good-cookies
import justgoodcookies from "just-good-cookies";
Install Tailwind (if you haven't already, see below)
Initialize JGC (see the previous example) ๐
The easiest way to get started with JGC is to use Tailwind's default configuration (their documentation is amazing). You do not need to change anything. Just download JGC (or install it using NPM) and write the path in the "content" object of your tailwind.config.js file.
However, if you want to use Tailwind with a custom prefix you must embed the new CDN: <script src="https://cdn.tailwindcss.com"></script>
.
Then add the tailwindPrefix
parameter in JGC.
Here's a basic example.
Tailwind Config:
<script>
tailwind.config = {
prefix: "jgc-",
};
</script>
JGC:
justgoodcookies.init({
tailwindPrefix: "jgc-",
locale: "it", // ISO 639-1 language code
layout: "style1",
privacyLink: "https://www.mysite.com/privacy-policy/",
cookies: {
necessary: {
title: "Necessary cookies",
description: "Some text to describe them",
},
},
});
JGC does not work with custom prefixes generated by JIT via Webpack, Rollup, Screw, and Parcel. For this reason.
Two options:
Let's see how to block a script or an iframe. It's pretty simple.
Get one, for example the Spotify widget:
<iframe
src="https://open.spotify.com/embed/album/1234567890"
width="300"
height="380"
frameborder="0"
allowtransparency="true"
allow="encrypted-media"
></iframe>
Change it to:
<iframe
data-jgc-tag="thirdparties"
data-jgc-src="https://open.spotify.com/embed/album/1234567890"
data-jgc-service="Spotify widget"
width="300"
height="380"
frameborder="0"
allowtransparency="true"
allow="encrypted-media"
></iframe>
Steps:
src
with data-jgc-src
data-jgc-tag
to describe the type of cookie.data-jgc-service
to give the cookie a "name" (this value is returned in the settings panel).And you're done. ๐
autoMode
(boolean) and autoCategories
(object)justgoodcookies.init({
autoMode: true,
autoCategories: {
youtube: ['Youtube', 'functionalities'], // example
spotify: ['Spotify', 'functionalities'], // example
google: ['Google', 'analytics'], // example
facebook: ['Facebook', 'marketing'], // example
},
locale: "en",
layout: "style1",
privacyLink: "https://www.mysite.com/privacy-policy/",
cookies: {
analytics: {
title: "Analtycs or another title",
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer pulvinar gravida urna quis vehicula. Vestibulum sed libero ultricies, facilisis nunc ut, accumsan magna.",
},
functionalities: {
title: "Functionalities or another title",
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer pulvinar gravida urna quis vehicula. Vestibulum sed libero ultricies, facilisis nunc ut, accumsan magna.",
},
necessary: {
title: "Necessary cookies",
description: "Lorem ipsum dolor sit amet, consectet",
},
},
)}
autoMode
is self-explanatory.
autoCategories
describes the scripts you want to block:
cookies
object).Okay, enough talking โ let's see a few examples. Suppose you have a script like the following:
<iframe
src="https://www.youtube.com/embed/1234567890"
width="560"
height="315"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write;"
allowfullscreen
>
</iframe>
To block it, you need to set autoMode
to true and populate autoCategories
in this way:
autoMode: true,
autoCategories: {
"www.youtube.com": ['Youtube Videos', 'functionalities'],
},
cookies: {
functionalities: {
title: "Functionalities or another title",
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit etc...",
},
//...and so on
},
The key ("www.youtube.com") is the domain name of the URL you are blocking.
In the array you have the name of the service (which is up to you) and the type (in this example: functionalities).
This type must be exactly the same key as that of the cookie
object.
See how it works?
Ok, another example: a FB widget.
<iframe
src="https://www.facebook.com/plugins/...."
scrolling="yes"
style="border:none; overflow:hidden; width:300px; height:500px; background: white; "
allowtransparency="true"
frameborder="0"
data-src="https://www.facebook.com/plugins/..."
></iframe>
This is what you have to do:
autoCategories: {
"www.facebook.com": ['Facebook Widget', 'marketing'],
},
cookies: {
marketing: {
title: "Marketing cookies",
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer pulvinar gravida urna quis vehicula. Vestibulum sed libero ultricies, facilisis nunc ut, accumsan magna.",
},
//...and so on
},
I hope that makes sense. I'll post more examples soon.
JGC allows you to define a placeholder (text or img) to overlay the blocked iFrames.
If you want to use a text placeholder add the attribute data-jgc-placeholder-text
.
<iframe
data-jgc-placeholder-text="This is a placeholder"
data-jgc-service="Spotify widget"
data-jgc-tag="thirdparties"
data-jgc-src="https://open.spotify.com/embed/album/1234567890"
width="300"
height="380"
frameborder="0"
allowtransparency="true"
allow="encrypted-media"
></iframe>
Sometimes you may want to use an image as a placeholder.
In that case use the data-jgc-placeholder-img
attribute.
<iframe
data-jgc-placeholder-img="https://images.unsplash.com/photo-1567095761054-7a02e69e5c43?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=987&q=80"
data-jgc-service="Spotify widget"
data-jgc-tag="thirdparties"
data-jgc-src="https://open.spotify.com/embed/album/1234567890"
width="300"
height="380"
frameborder="0"
allowtransparency="true"
allow="encrypted-media"
></iframe>
Now, suppose you are using autoMode (or manual mode) and want to load a generic placeholder over all blocked iFrames. It's simple, add this object to your script:
placeholder: {
text: "This is a placeholder <br/> Click here to change preferences.",
classes: 'bg-green-200 text-white bg-cover text-center', // use some classes to center or stylize the placeholder
}
or this one:
placeholder: {
classes: 'bg-cover',
image: 'https://images.unsplash.com/photo-1607827448387-a67db1383b59?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2670&q=80'
}
How cool is that, huh?
data-jgc-remove
In other situations, you will have to deal with scripts that are almost impossible to block (they release cookies even if you change the "src" attribute).
In these special cases, you can either use autoMode (hiding the scripts with the css) or manual mode adding the data-jgc-remove
attribute on the parent div.
A few notes about the data-jgc-remove
implementation:
data-jgc-service
and data-jgc-tag
must be placed on the parent div (keeping the original script with the default attributes)Example:
<div
data-jgc-remove
data-jgc-service="Not so impossible to block after all"
data-jgc-tag="marketing"
>
<script
type="text/javascript"
src="https://impossiblesitetoblock.com/jsform/1234"
></script>
</div>
It's pretty simple ๐ฅณ
Here is an example of all properties that can be set during initialization:
<script>
justgoodcookies.init({
locale: "it",
layout: "style1",
privacyLink: "https://www.mysite.com/privacy-policy/",
cookieDuration: 182, // in days, default cookie duration 360 days
tailwindPrefix: "jgc-",
dark: true,
banner: {
animation: true,
backgroundColor:'bg-color',
backgroundDark: true,
backgroundImage: '/path/to/image.jpg',
closeButton: false,
closeButtonAccept: true,
disableReject: false,
icon: "/assets/cookies_icon.svg",
iconDark: "/assets/cookies_icon_dark.svg",
innerBackgroundImage: '/assets/cookies-style6.svg',
logo: "/assets/logo.svg",
logoClasses: 'w-2/4',
maxWidth: 'xl',
onAccept(){},
onReject(){},
position: "bottom",
shortText: false,
title: "Custom title",
},
cookies: {
necessary: { // MANDATORY
title: "Necessary cookies",
description: "Lorem ipsum dolor sit amet,consectet",
},
// analytcs here is an example, just "necessary" is mandatory
analytics: {
title: "Analtycs or another title",
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer pulvinar gravida urna quis vehicula. Vestibulum sed libero ultricies, facilisis nunc ut, accumsan magna.",
},
},
placeholder: {
text: "This is a placeholder <br/> Click here to change preferences.",
classes: 'bg-green-200 text-white bg-cover text-center',
image: 'https://images.unsplash.com/photo-1638913976954-8f7b612867c2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2670&q=80'
},
text: {
acceptSelectedText: 'custom text',
acceptText: 'custom text',
bannerLinkLabel: 'custom text',
descriptionText: 'custom text',
panelTitle: 'custom text',
preferencesText: 'custom text',
rejectText: 'custom text',
saveButton: 'custom text',
saveAllButton: 'custom text',
servicesTag: 'custom text'
},
style: {
accept: 'mt-2 text-green-600',
bannerText: 'text-green-800',
bannerTitle: '"text-white',
closeButton: 'text-sky-100 bg-black',
lockIcon: "text-red-500",
panelHeader: 'md:flex justify-between px-4 py-4',
panelText: 'text-red-300',
panelTitle: 'text-white',
preferencesText: 'text-black mt-4 border-0',
privacyLink: 'text-black font-bold text-sm',
reject: 'text-red-800 font-semibold text-xs px-2 py-0.5 mt-2',
saveButton: 'text-md font-bold bg-white text-red-800 hover:bg-red-900',
saveAllButton: 'text-md font-bold bg-white text-red-800 hover:bg-red-900',
servicesTag: 'text-white',
servicesText: 'text-yellow-400',
stripes:'odd:bg-green-100 even:bg-green-800',
toggles: 'bg-red-800',
},
activate: {
GoogleTagManager: {
container_id: 'GTM-EXAMPLE',
dataJgcTag:"necessary", // The JGC tag of this script
dataJgcService:"GoogleTagManager", // Custom name
event_name: 'jgc-cookies-accepted', // example
variables: [
['author', 'test'], // example
['price', 'test'] // example
]
},
GoogleAnalytics: {
id: 'G-EXAMPLE', // example
anonymized: true,
dataJgcTag:"necessary", // cookie tag
dataJgcService:"Google Analytics", // custom name
ad_storage: false,
analytics_storage: false
},
FacebookPixel: {
init: 'EXAMPLE', // example
dataJgcTag: 'functionalities', // cookie tag
dataJgcService:"Facebook Pixel", // custom name
},
},
panel: {
bgColor: 'bg-red-900',
open: true,
padding: false,
},
});
</script>
Here you find the basic (and most important) parameters
Parameters:
Parameter | Type | Default | Values | Scope | Mandatory |
---|---|---|---|---|---|
locale | String | 'en' | 'en', 'it', and I'll add more languages soon | Define the locale (ISO 639-1 language code) | yes |
layout | String | 'style1' | 'style1', 'style2', 'style3', 'style4', 'style5', 'style6', 'style7', 'style8', 'style9' | The style of the banner | yes |
privacyLink | String | An absolute url | example: 'https://www.mysite.com/privacy-policy/' | The privacy policy | yes |
cookieDuration | Number | 360 | Any integer | Default cookie duration, in days | no |
tailwindPrefix | String | '' | Example "jgc-" | A custom tailwind prefix, if you need it. | no |
dark | Boolean | false | true, false | If true, the script is forced to check if the user has set the computer to dark mode, and if so, a class is added to the html tag | no |
Choose your favorite layout and customize it (and soon I will make more).
style1
, style2
, style3
, style4
, style5
, style6
, style7
are generic styles (only the layouts are different, not the functions).
style1
is the most compatible of all and the only one recommended in most situations (as long as JGC remains in BETA, this is the recommended layout).
style8
is the only one that displays the banner and the settings toggles at the same time.
style9
is extremely minimalistic and to use it correctly you must specify true in the 'shortText' parameter:
...
banner: {
shortText: true, // this option is used to shorten the text of the banner
}
...
Dark mode is available for all styles
Be sure to comply with your state's regulations (especially when using the 'style9').
With the object Text
you can overwrite labels, buttons and texts.
This is an optional object. If you do not use it, JGC will fetch the texts from "locale"
Object:
text: {
acceptSelectedText: 'custom text', // Accept selected cookies
acceptText: 'custom text', // Accept button
bannerLinkLabel: 'custom text', // Privacy policy link label
descriptionText: 'custom text', // Banner description
panelTitle: 'custom text', // Panel title
preferencesText: 'custom text', // Preferences link
rejectText: 'custom text', // Reject button
saveButton: 'custom text', // Save button
saveAllButton: 'custom text', // Save and accept all cookies
servicesTag: 'custom text' // Services tag label
}
The banner
object allows you to change the appearance of the banner, add a logo or icon, and customize the background (with a color or image).
You can also run a callback on completion (if users accept or reject cookies).
All these properties are OPTIONAL
Object:
banner: {
animation: true, // Boolean: Turn off banner's animation
backgroundColor:'my-custom-bg', // String: Background color of the banner
backgroundDark: true, // Boolean: Add a dark overlay
backgroundImage: '/assets/image.jpg', // String: Add an external background image to the banner
closeButton: false, // Boolean: Show or hide the X button
closeButtonAccept: true, // Boolean: Allow you to accept cookies after clicking the X (or refuse all)
icon: "/assets/cookies_icon.svg", // String: An Icon
iconDark: "/assets/cookies_icon_dark.svg", // String: The dark version of the Icon
innerBackgroundImage: '/assets/image.jpg', // String: Insert inner image into the banner
logo: "/assets/logo.svg", // String: Load a logo. Can be a relative or absolute path
logoClasses: 'w-2/4', // String: CSS classes for the logo
maxWidth: '3xl', // String: A Tailwind breakpoint to define the maximum width of the banner
onAccept(){ // Function: Fire on "accept"
console.log('accepted');
},
onReject(){ // Function: Fire on "reject"
console.log('rejected');
},
position: "top", // String: Position of the banner (top", "bottom", "center")
shortText: true, // Boolean: It shorts texts automatically
title: 'Cookie consent', // String: The Banner title
}
If you use the callbacks
onAccept
andonReject
, the automatic page refresh disabled. You can add it manually, so that you have full control over these actions.
The placeholder
object allows you to define a generic text or image that overlays the blocked iframes.
The placeholder is always clickable, so that users can change their settings
Object:
placeholder: {
text: "This is a placeholder. Click here to change preferences.", // The text of the placeholder
classes: 'bg-green-200 text-white bg-cover text-center', // Some classes you can use to stylize the placeholder
image: 'https://images.unsplash.com/photo-1638913976954-8f7b612867c2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2670&q=80' // A URL
},
With the object style
you can stylize the banner elements adding custom CSS classes.
โ ๏ธ ATTENTION. These rules completely override the style of the individual elements.
If you want to keep the original alignment of these elements, I recommend that you also copy the original classes from JGC. โ ๏ธ
Object:
style: {
accept: 'mt-2 text-green-600', // Accept button
bannerText: 'text-green-800', // Banner Text
bannerTitle: 'text-white', // Banner Title
closeButton: 'text-sky-100 bg-black', // Close button
lockIcon: "text-red-500", // Lock Icon
panelHeader: 'md:flex justify-between px-4 py-4', // Panel Header
panelText: 'text-red-300', // Panel Text
panelTitle: 'text-white', // Panel Title
preferencesText: 'text-black mt-4 border-0', // Preferences Text
privacyLink: 'text-black font-bold text-sm', // Privacy Link
reject: 'text-red-800 font-semibold text-xs px-2 py-0.5 mt-2', // Reject button
saveButton: 'text-md font-bold bg-white text-red-800', // Save button
saveAllButton: 'text-md font-bold bg-white text-red-800', // Save and accept all button
servicesTag: 'text-white', // Services name
servicesText: 'text-yellow-400', // Services description
stripes:'odd:bg-green-100 even:bg-green-800', // Here you can change the colors of the lines of the panel
toggles: 'bg-red-800', // Panel
}
Here you must define the cookie categories (and this part is a bit different from the other objects).
By default, you only need the necessary
category to run JGC (because if you don't have at LEAST one technical cookie...you probably don't need JGC).
For each category you must define a title
and a description
.
Object:
cookies: {
necessary: {
title : 'Necessary cookies',
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
}
}
Parameters:
Parameter | Type | Default | Values | Scope | Mandatory |
---|---|---|---|---|---|
necessary | Object | null | { title : 'your title here', description: 'your description here' } | The mandatory cookies for the preference panel | yes |
Then, if you have other cookie categories, you can expand the object in this way:
cookies: {
analytics: {
title: "Analtycs or another title",
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer pulvinar gravida urna quis vehicula. Vestibulum sed libero ultricies, facilisis nunc ut, accumsan magna.",
},
functionalities: {
title: "Functionalities or another title",
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer pulvinar gravida urna quis vehicula. Vestibulum sed libero ultricies, facilisis nunc ut, accumsan magna.",
},
necessary: {
title: "Necessary cookies",
description: "Lorem ipsum dolor sit amet, consectet",
},
}
For each category, the object's key must match the same name that you use as value for data-jgc-tag
on your scripts or within the autoCategories
during autoMode.
An example: if the key is called "analytics", then you should have at least one script on your site with data-jgc-tag='analytics'
or something like the following within the autoCategories
:
autoCategories: {
"domaintoblock.com": ['A nice analytics tool', 'analytics'],
},
Read here how to translate these fields
โ ๏ธ If the attribute and category key do not match, the script will not appear in the preferences panel โ ๏ธ
Enable scripts automatically without manually inserting them into the code. You can currently install Google Analytics, Google Tag Manager and Facebook Pixel.
Object:
activate: {
GoogleTagManager: {
container_id: 'GTM-EXAMPLE', // container ID
dataJgcTag:"necessary", // The JGC tag of this script
dataJgcService:"GoogleTagManager", // Custom name
event_name: 'jgc-cookies-accepted', // Event Name
variables: [ // Optional, some variables as array key/value
['author', 'test'],
['price', 'test']
]
},
GoogleAnalytics: {
id: 'G-EXAMPLE', // ID
anonymized: true, // If you want to anonymize the data, boolean
dataJgcTag:"necessary", // The JGC tag of this script
dataJgcService:"Google Analytics", // Custom name
ad_storage: false, // Boolean
analytics_storage: false // Boolean
},
FacebookPixel: {
init: 'IDEXAMPLE', // Init ID
dataJgcTag: 'functionalities', // The JGC tag of this script
dataJgcService:"Facebook Pixel", // Custom name
},
}
Use the panel
object to configure the settings panel.
Object:
panel: {
bgColor: 'bg-red-900', // Changes the bg color
open: true, // Opens the panel on page load
padding: false, // Removes the padding
}
Just Good Cookies is released under the MIT license (MIT). Please see the license file for more information. This is a free tool provided without warranty of any kind, not a service. If you use this script, you will always remain the sole responsible party, use it at your own risk.
Even though Tailwind CSS is not built-in I still want to mention that it is released under the MIT license and you can find everything you need in their online documentation (Adam, if you read this, thank you very much for Tailwind! ๐คฉ).
FAQs
A delicious cookie consent solution for complying with EU cookie law
The npm package just-good-cookies receives a total of 0 weekly downloads. As such, just-good-cookies popularity was classified as not popular.
We found that just-good-cookies demonstrated a not healthy version release cadence and project activity because the last version was released a year ago.ย It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
Security News
As cyber threats become more autonomous, AI-powered defenses are crucial for businesses to stay ahead of attackers who can exploit software vulnerabilities at scale.
Security News
UnitedHealth Group disclosed that the ransomware attack on Change Healthcare compromised protected health information for millions in the U.S., with estimated costs to the company expected to reach $1 billion.