How to save and load cookies in Playwright?

To save and load cookies in Playwright, use the browser context's cookies() method to export the current session's cookies, then add_cookies() to restore them into a context later. This lets you skip a login flow or restore browsing state between script runs instead of repeating it every time.

Saving cookies

context.cookies() returns a list of dictionaries, one per cookie, each containing fields like name, value, domain, path, expires, httpOnly, secure, and sameSite. Serialize the list to JSON and write it to a file so you can reuse it later.

import json

with open("cookies.json", "w") as f:
    json.dump(context.cookies(), f)

Loading cookies

Read the JSON file back and pass the resulting list directly to context.add_cookies(). The fields returned by cookies() are already in the exact shape add_cookies() expects, so no conversion is needed.

import json

with open("cookies.json", "r") as f:
    context.add_cookies(json.load(f))

Call add_cookies() before navigating to the target page if you want that page's first request to include the cookies. Adding cookies after the page has already loaded won't resend the original request with them attached.

Full example

import json
from playwright.sync_api import sync_playwright

# First run: perform login and save cookies
with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    context = browser.new_context()
    page = context.new_page()
    page.goto("https://example.com/login")
    # ... fill and submit login form ...
    with open("cookies.json", "w") as f:
        json.dump(context.cookies(), f)

# Second run: restore cookies into a fresh context
with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    context = browser.new_context()
    with open("cookies.json", "r") as f:
        context.add_cookies(json.load(f))
    page = context.new_page()
    page.goto("https://example.com/dashboard")  # loads as authenticated

The two with sync_playwright() blocks represent separate script runs. Cookies saved in the first run are loaded into a completely new context in the second, which is how you skip a login flow in practice.

Common errors and limitations

  • Missing url or domain/path: add_cookies() requires each cookie dict to include either a url, or both domain and path. Cookies returned by context.cookies() already include these, but a hand-built cookie dict will raise an error if you leave them out.
  • Cookies don't apply retroactively: adding cookies after a page has already loaded doesn't resend that page's request. Call add_cookies() before page.goto() if the target page needs to see the cookies on its first load.
  • Expired cookies won't restore a session: add_cookies() will load expired cookies without error, but the target site won't treat the session as authenticated. If a site rejects a restored session, re-run the login flow and re-save cookies.json.
  • Persisting localStorage and sessionStorage: add_cookies() only restores cookies. If you also need to preserve web storage, use context.storage_state(path="state.json") to save everything in one call and browser.new_context(storage_state="state.json") to restore it.

Related Playwright web scraping questions: