1 | <p align="center">
|
2 | <img src="https://cloud.githubusercontent.com/assets/835857/14581711/ba623018-0436-11e6-8fce-d2ccd4d379c9.gif">
|
3 | </p>
|
4 |
|
5 | # JavaScript Cookie [![CI](https://github.com/js-cookie/js-cookie/actions/workflows/ci.yml/badge.svg)](https://github.com/js-cookie/js-cookie/actions/workflows/ci.yml) [![BrowserStack](https://github.com/js-cookie/js-cookie/actions/workflows/browserstack.yml/badge.svg)](https://github.com/js-cookie/js-cookie/actions/workflows/browserstack.yml) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com) [![Code Climate](https://codeclimate.com/github/js-cookie/js-cookie.svg)](https://codeclimate.com/github/js-cookie/js-cookie) [![npm](https://img.shields.io/github/package-json/v/js-cookie/js-cookie)](https://www.npmjs.com/package/js-cookie) [![size](https://img.shields.io/bundlephobia/minzip/js-cookie/3)](https://www.npmjs.com/package/js-cookie) [![jsDelivr Hits](https://data.jsdelivr.com/v1/package/npm/js-cookie/badge?style=rounded)](https://www.jsdelivr.com/package/npm/js-cookie)
|
6 |
|
7 | A simple, lightweight JavaScript API for handling cookies
|
8 |
|
9 | - Works in [all](https://www.browserstack.com/automate/public-build/b3VDaHAxVDg0NDdCRmtUOWg0SlQzK2NsRVhWTjlDQS9qdGJoak1GMzJiVT0tLVhwZHNvdGRoY284YVRrRnI3eU1JTnc9PQ==--5e88ffb3ca116001d7ef2cfb97a4128ac31174c2) browsers
|
10 | - Accepts [any](#encoding) character
|
11 | - [Heavily](test) tested
|
12 | - No dependency
|
13 | - Supports ES modules
|
14 | - Supports AMD/CommonJS
|
15 | - [RFC 6265](https://tools.ietf.org/html/rfc6265) compliant
|
16 | - Useful [Wiki](https://github.com/js-cookie/js-cookie/wiki)
|
17 | - Enable [custom encoding/decoding](#converters)
|
18 | - **< 800 bytes** gzipped!
|
19 |
|
20 | **ππ If you're viewing this at https://github.com/js-cookie/js-cookie, you're reading the documentation for the main branch.
|
21 | [View documentation for the latest release.](https://github.com/js-cookie/js-cookie/tree/latest#readme) ππ**
|
22 |
|
23 | ## Installation
|
24 |
|
25 | ### NPM
|
26 |
|
27 | JavaScript Cookie supports [npm](https://www.npmjs.com/package/js-cookie) under the name `js-cookie`.
|
28 |
|
29 | ```bash
|
30 | npm i js-cookie
|
31 | ```
|
32 |
|
33 | The npm package has a `module` field pointing to an ES module variant of the library, mainly to provide support for ES module aware bundlers, whereas its `browser` field points to an UMD module for full backward compatibility.
|
34 |
|
35 | _Not all browsers support ES modules natively yet_. For this reason the npm package/release provides both the ES and UMD module variant and you may want to include the ES module along with the UMD fallback to account for this:
|
36 |
|
37 | ### CDN
|
38 |
|
39 | Alternatively, include js-cookie via [jsDelivr CDN](https://www.jsdelivr.com/package/npm/js-cookie).
|
40 |
|
41 | ## Basic Usage
|
42 |
|
43 | Create a cookie, valid across the entire site:
|
44 |
|
45 | ```javascript
|
46 | Cookies.set('name', 'value')
|
47 | ```
|
48 |
|
49 | Create a cookie that expires 7 days from now, valid across the entire site:
|
50 |
|
51 | ```javascript
|
52 | Cookies.set('name', 'value', { expires: 7 })
|
53 | ```
|
54 |
|
55 | Create an expiring cookie, valid to the path of the current page:
|
56 |
|
57 | ```javascript
|
58 | Cookies.set('name', 'value', { expires: 7, path: '' })
|
59 | ```
|
60 |
|
61 | Read cookie:
|
62 |
|
63 | ```javascript
|
64 | Cookies.get('name') // => 'value'
|
65 | Cookies.get('nothing') // => undefined
|
66 | ```
|
67 |
|
68 | Read all visible cookies:
|
69 |
|
70 | ```javascript
|
71 | Cookies.get() // => { name: 'value' }
|
72 | ```
|
73 |
|
74 | _Note: It is not possible to read a particular cookie by passing one of the cookie attributes (which may or may not
|
75 | have been used when writing the cookie in question):_
|
76 |
|
77 | ```javascript
|
78 | Cookies.get('foo', { domain: 'sub.example.com' }) // `domain` won't have any effect...!
|
79 | ```
|
80 |
|
81 | The cookie with the name `foo` will only be available on `.get()` if it's visible from where the
|
82 | code is called; the domain and/or path attribute will not have an effect when reading.
|
83 |
|
84 | Delete cookie:
|
85 |
|
86 | ```javascript
|
87 | Cookies.remove('name')
|
88 | ```
|
89 |
|
90 | Delete a cookie valid to the path of the current page:
|
91 |
|
92 | ```javascript
|
93 | Cookies.set('name', 'value', { path: '' })
|
94 | Cookies.remove('name') // fail!
|
95 | Cookies.remove('name', { path: '' }) // removed!
|
96 | ```
|
97 |
|
98 | _IMPORTANT! When deleting a cookie and you're not relying on the [default attributes](#cookie-attributes), you must pass the exact same path and domain attributes that were used to set the cookie:_
|
99 |
|
100 | ```javascript
|
101 | Cookies.remove('name', { path: '', domain: '.yourdomain.com' })
|
102 | ```
|
103 |
|
104 | _Note: Removing a nonexistent cookie neither raises any exception nor returns any value._
|
105 |
|
106 | ## Namespace conflicts
|
107 |
|
108 | If there is any danger of a conflict with the namespace `Cookies`, the `noConflict` method will allow you to define a new namespace and preserve the original one. This is especially useful when running the script on third party sites e.g. as part of a widget or SDK.
|
109 |
|
110 | ```javascript
|
111 | // Assign the js-cookie api to a different variable and restore the original "window.Cookies"
|
112 | var Cookies2 = Cookies.noConflict()
|
113 | Cookies2.set('name', 'value')
|
114 | ```
|
115 |
|
116 | _Note: The `.noConflict` method is not necessary when using AMD or CommonJS, thus it is not exposed in those environments._
|
117 |
|
118 | ## Encoding
|
119 |
|
120 | This project is [RFC 6265](http://tools.ietf.org/html/rfc6265#section-4.1.1) compliant. All special characters that are not allowed in the cookie-name or cookie-value are encoded with each one's UTF-8 Hex equivalent using [percent-encoding](http://en.wikipedia.org/wiki/Percent-encoding).
|
121 | The only character in cookie-name or cookie-value that is allowed and still encoded is the percent `%` character, it is escaped in order to interpret percent input as literal.
|
122 | Please note that the default encoding/decoding strategy is meant to be interoperable [only between cookies that are read/written by js-cookie](https://github.com/js-cookie/js-cookie/pull/200#discussion_r63270778). To override the default encoding/decoding strategy you need to use a [converter](#converters).
|
123 |
|
124 | _Note: According to [RFC 6265](https://tools.ietf.org/html/rfc6265#section-6.1), your cookies may get deleted if they are too big or there are too many cookies in the same domain, [more details here](https://github.com/js-cookie/js-cookie/wiki/Frequently-Asked-Questions#why-are-my-cookies-being-deleted)._
|
125 |
|
126 | ## Cookie Attributes
|
127 |
|
128 | Cookie attribute defaults can be set globally by creating an instance of the api via `withAttributes()`, or individually for each call to `Cookies.set(...)` by passing a plain object as the last argument. Per-call attributes override the default attributes.
|
129 |
|
130 | ### expires
|
131 |
|
132 | Define when the cookie will be removed. Value must be a [`Number`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number) which will be interpreted as days from time of creation or a [`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) instance. If omitted, the cookie becomes a session cookie.
|
133 |
|
134 | To create a cookie that expires in less than a day, you can check the [FAQ on the Wiki](https://github.com/js-cookie/js-cookie/wiki/Frequently-Asked-Questions#expire-cookies-in-less-than-a-day).
|
135 |
|
136 | **Default:** Cookie is removed when the user closes the browser.
|
137 |
|
138 | **Examples:**
|
139 |
|
140 | ```javascript
|
141 | Cookies.set('name', 'value', { expires: 365 })
|
142 | Cookies.get('name') // => 'value'
|
143 | Cookies.remove('name')
|
144 | ```
|
145 |
|
146 | ### path
|
147 |
|
148 | A [`String`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) indicating the path where the cookie is visible.
|
149 |
|
150 | **Default:** `/`
|
151 |
|
152 | **Examples:**
|
153 |
|
154 | ```javascript
|
155 | Cookies.set('name', 'value', { path: '' })
|
156 | Cookies.get('name') // => 'value'
|
157 | Cookies.remove('name', { path: '' })
|
158 | ```
|
159 |
|
160 | **Note regarding Internet Explorer:**
|
161 |
|
162 | > Due to an obscure bug in the underlying WinINET InternetGetCookie implementation, IEβs document.cookie will not return a cookie if it was set with a path attribute containing a filename.
|
163 |
|
164 | (From [Internet Explorer Cookie Internals (FAQ)](http://blogs.msdn.com/b/ieinternals/archive/2009/08/20/wininet-ie-cookie-internals-faq.aspx))
|
165 |
|
166 | This means one cannot set a path using `window.location.pathname` in case such pathname contains a filename like so: `/check.html` (or at least, such cookie cannot be read correctly).
|
167 |
|
168 | In fact, you should never allow untrusted input to set the cookie attributes or you might be exposed to a [XSS attack](https://github.com/js-cookie/js-cookie/issues/396).
|
169 |
|
170 | ### domain
|
171 |
|
172 | A [`String`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) indicating a valid domain where the cookie should be visible. The cookie will also be visible to all subdomains.
|
173 |
|
174 | **Default:** Cookie is visible only to the domain or subdomain of the page where the cookie was created, except for Internet Explorer (see below).
|
175 |
|
176 | **Examples:**
|
177 |
|
178 | Assuming a cookie that is being created on `site.com`:
|
179 |
|
180 | ```javascript
|
181 | Cookies.set('name', 'value', { domain: 'subdomain.site.com' })
|
182 | Cookies.get('name') // => undefined (need to read at 'subdomain.site.com')
|
183 | ```
|
184 |
|
185 | **Note regarding Internet Explorer default behavior:**
|
186 |
|
187 | > Q3: If I donβt specify a DOMAIN attribute (for) a cookie, IE sends it to all nested subdomains anyway?
|
188 | > A: Yes, a cookie set on example.com will be sent to sub2.sub1.example.com.
|
189 | > Internet Explorer differs from other browsers in this regard.
|
190 |
|
191 | (From [Internet Explorer Cookie Internals (FAQ)](http://blogs.msdn.com/b/ieinternals/archive/2009/08/20/wininet-ie-cookie-internals-faq.aspx))
|
192 |
|
193 | This means that if you omit the `domain` attribute, it will be visible for a subdomain in IE.
|
194 |
|
195 | ### secure
|
196 |
|
197 | Either `true` or `false`, indicating if the cookie transmission requires a secure protocol (https).
|
198 |
|
199 | **Default:** No secure protocol requirement.
|
200 |
|
201 | **Examples:**
|
202 |
|
203 | ```javascript
|
204 | Cookies.set('name', 'value', { secure: true })
|
205 | Cookies.get('name') // => 'value'
|
206 | Cookies.remove('name')
|
207 | ```
|
208 |
|
209 | ### sameSite
|
210 |
|
211 | A [`String`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String), allowing to control whether the browser is sending a cookie along with cross-site requests.
|
212 |
|
213 | Default: not set.
|
214 |
|
215 | **Note that more recent browsers are making "Lax" the default value even without specifiying anything here.**
|
216 |
|
217 | **Examples:**
|
218 |
|
219 | ```javascript
|
220 | Cookies.set('name', 'value', { sameSite: 'strict' })
|
221 | Cookies.get('name') // => 'value'
|
222 | Cookies.remove('name')
|
223 | ```
|
224 |
|
225 | ### Setting up defaults
|
226 |
|
227 | ```javascript
|
228 | const api = Cookies.withAttributes({ path: '/', domain: '.example.com' })
|
229 | ```
|
230 |
|
231 | ## Converters
|
232 |
|
233 | ### Read
|
234 |
|
235 | Create a new instance of the api that overrides the default decoding implementation. All get methods that rely in a proper decoding to work, such as `Cookies.get()` and `Cookies.get('name')`, will run the given converter for each cookie. The returned value will be used as the cookie value.
|
236 |
|
237 | Example from reading one of the cookies that can only be decoded using the `escape` function:
|
238 |
|
239 | ```javascript
|
240 | document.cookie = 'escaped=%u5317'
|
241 | document.cookie = 'default=%E5%8C%97'
|
242 | var cookies = Cookies.withConverter({
|
243 | read: function (value, name) {
|
244 | if (name === 'escaped') {
|
245 | return unescape(value)
|
246 | }
|
247 | // Fall back to default for all other cookies
|
248 | return Cookies.converter.read(value, name)
|
249 | }
|
250 | })
|
251 | cookies.get('escaped') // ε
|
252 | cookies.get('default') // ε
|
253 | cookies.get() // { escaped: 'ε', default: 'ε' }
|
254 | ```
|
255 |
|
256 | ### Write
|
257 |
|
258 | Create a new instance of the api that overrides the default encoding implementation:
|
259 |
|
260 | ```javascript
|
261 | Cookies.withConverter({
|
262 | write: function (value, name) {
|
263 | return value.toUpperCase()
|
264 | }
|
265 | })
|
266 | ```
|
267 |
|
268 | ## TypeScript declarations
|
269 |
|
270 | ```bash
|
271 | npm i @types/js-cookie
|
272 | ```
|
273 |
|
274 | ## Server-side integration
|
275 |
|
276 | Check out the [Servers Docs](SERVER_SIDE.md)
|
277 |
|
278 | ## Contributing
|
279 |
|
280 | Check out the [Contributing Guidelines](CONTRIBUTING.md)
|
281 |
|
282 | ## Security
|
283 |
|
284 | For vulnerability reports, send an e-mail to `js-cookie at googlegroups dot com`
|
285 |
|
286 | ## Releasing
|
287 |
|
288 | Releasing should be done via the `Release` GitHub Actions workflow, so that published packages on npmjs.com have package provenance.
|
289 |
|
290 | GitHub releases are created as a draft and need to be published manually!
|
291 | (This is so we are able to craft suitable release notes before publishing.)
|
292 |
|
293 | ## Supporters
|
294 |
|
295 | <p>
|
296 | <a href="https://www.browserstack.com/"><img src="https://raw.githubusercontent.com/wiki/js-cookie/js-cookie/Browserstack-logo%402x.png" width="150"></a>
|
297 | </p>
|
298 |
|
299 | Many thanks to [BrowserStack](https://www.browserstack.com/) for providing unlimited browser testing free of cost.
|
300 |
|
301 | ## Authors
|
302 |
|
303 | - [Klaus Hartl](https://github.com/carhartl)
|
304 | - [Fagner Brack](https://github.com/FagnerMartinsBrack)
|
305 | - And awesome [contributors](https://github.com/js-cookie/js-cookie/graphs/contributors)
|