Skip to content

fix(deps): update dependency @c15t/nextjs to v3 - #453

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/c15t-nextjs-3.x
Open

renovate[bot] wants to merge 1 commit into
mainfrom
renovate/c15t-nextjs-3.x

Conversation

@renovate

@renovate renovate Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
@c15t/nextjs (source) 2.4.1 → 3.2.2 age confidence

Release Notes

c15t/c15t (@​c15t/nextjs)

v3.2.2

Compare Source

Published @​c15t/nextjs@3.2.2.

v3.2.1

Compare Source

Published @​c15t/nextjs@3.2.1.

v3.2.0

Compare Source

Match the stock surfaces' text direction and IAB handling in headless UI

useConsentTextDirection() returns 'rtl' or 'ltr' for the language
c15t shows consent copy in. Set it as dir on a custom banner or
preference center, as the stock ones do, so a visitor whose browser
language runs right to left gets a mirrored layout.

useIABPolicyGuard() is now public. A custom surface that handles only
opt-in and opt-out calls it and returns null when useModel() is
'iab'. The guard throws IABUnavailableError while rendering when the
policy needs IAB and the app never loaded <IABProvider>.

Import both from c15t/react/headless, c15t/next/headless or
c15t/tanstack-start/headless.

Set the subject ID cookie on the server

The framework adapters now give a new visitor a subject ID on their first
request. The server sets it in the c15t-sid cookie and the server render
uses the same ID, so the browser starts with it instead of creating its own.
The cookie holds only the ID: the banner still shows until the visitor
decides.

  • Next.js: c15tProxy sets the cookie and forwards it on the request, so
    resolveConsent in the same request reads it. withConsentProps sets it
    for Pages Router pages. Both accept storage, trustForwardedHeaders
    and subjectCookie. Without the proxy, App Router pages leave it to the
    browser.
  • TanStack Start: consentRequestMiddleware sets it and accepts the same
    options. Prerendered pages get none.
  • Astro: the c15t middleware sets it on server-rendered pages, named from
    storageConfig. middleware.trustForwardedHeaders and
    middleware.subjectCookie are new. With a consentSource, pass
    subjectCookie: false.
  • SvelteKit: c15tHandle sets it and exposes the request cookie as
    locals.c15t.cookie. storage, trustForwardedHeaders and
    subjectCookie are new options. With persistence: false or a
    consentSource on ConsentProvider, pass subjectCookie: false.
  • Nuxt: the plugin sets it during server rendering, except for prerendered
    and cached routes.

Prefetch and prerender requests, and responses marked as shared, never get a
cookie, because every visitor who received it would share the ID. Neither does
the consent route, which renders no page and serves its manifest as public
data a shared cache keeps: Next.js skips the routePrefix in
c15t.config.ts, SvelteKit and Astro skip their routePrefix, and each falls
back to /api/c15t. The Next.js proxy and the SvelteKit handle run before
the response exists, so pass subjectCookie: false for requests to other
routes a shared cache keeps, such as a public API route or feed; the
consent headers are still normalized. TanStack Start sees the response: a
page whose resolveConsent read the visitor's cookies holds the visitor's
consent and subject ID, so it is sent private with the cookie, keeping
its browser directives, and without the CDN cache fields, such as
CDN-Cache-Control and Surrogate-Control, that a CDN honouring them reads
in place of Cache-Control. A response with no such render that sets
public, s-maxage, max-age, no-cache or Expires, or a CDN cache field
that lets the CDN store it, gets no cookie, and
TanStack Start sends the consent route's responses unchanged, wherever it is
mounted. Render HTML you cache for every
visitor with shared: true. Pass the same storage options as the
browser so the cookie has the same name, domain and lifetime. With
persistence={false} or a consentSource on ConsentRoot, pass
subjectCookie: false so the server sets no cookie.

On another server, resolveRequestSubject() from c15t/server returns the
visitor's ID, the Set-Cookie value to send and the request Cookie header
to render with.

A subject ID with an unpaired UTF-16 surrogate gets no subject cookie, and the
server keeps the ID its records carry. TanStack Start's server-render state
replaces that surrogate with U+FFFD on the way to the browser; see the
TanStack Start docs for when the browser keeps the changed ID.

The server helpers read a Node-style header record under any header-name
casing. resolveRequestSubject() and readRequestConsent() find a Cookie or
COOKIE header, and the request origin finds Host. Forwarding headers are
still read only with trustForwardedHeaders: true.

The server and the adapters never replace a c15t-sid cookie the request
already has. While the browser's cookie writes succeed, the server render and
the browser use the same ID. The server reads cookies only, though. If the
browser refuses to rewrite a record cookie after the subject ID changes, a
server render keeps reporting the old ID that cookie holds, and the browser
starts with the new ID from its localStorage. This happens even when the
request's c15t-sid cookie already holds the new ID. It lasts until a later
write of that record reaches the cookie, which may never happen while the
browser keeps refusing it.

With crossSubdomain, a visitor whose only record is a vendor decision can hold
a local vendor copy and a shared cookie copy with the same decision time but
different subject IDs, because a rekey keeps the original decision time. As
before, a page that hydrates from storage starts with the local copy's ID.
Server-rendered pages now do the same. The runtime does not write that ID over a
shared c15t-sid cookie the record cookies agree with, but a later vendor save
from this origin stores it in the shared vendor cookie, and after that a later
page load can store it in the shared c15t-sid cookie too. The ID mismatch on
its own grants no optional category and lifts no denial; that vendor save
changes only the vendor decisions it names.

Rename offline mode to local() and warn that it keeps no consent records

offline() is now local() in every framework package, in c15t and in
c15t/modes. offline() still works and is marked deprecated. c15t v4 removes
it.

In development builds, local mode logs one console.warn per page: c15t keeps
no server-side record of consent, and with no geolocation every visitor gets
the same policy. Production builds never log it, and it blocks nothing. Pass
local({ acknowledgeNoRecords: true }) to hide it once you have decided a
browser-only record is enough. c15t v4 will require that option.

The script tag's local-mode file is now c15t.local.js. c15t.offline.js
still ships until v4, and on development hosts it logs its new name. Script-tag files are production builds, so
they log the warning only on development hosts such as localhost. Add
data-acknowledge-no-records to the tag to hide it. c15t.local() joins the
script-tag global.

c15t setup labels local mode "Development and tests only, no consent records"
and generates local().

Lock page scroll from a headless banner

useScrollLock(shouldLock) locks page scroll the way the stock banner does
when its policy is blocking. Call it with
banner.isVisible && banner.blocking from useHeadlessConsentUI(). Locks
are counted, so the page scrolls again once every surface holding one lets
go. Import it from c15t/react/headless, c15t/next/headless or
c15t/tanstack-start/headless.

Stream a headless banner with StreamedConsentSurface

StreamedConsentSurface lets a banner built with the headless hooks stream
like the stock ConsentBanner. With Next.js
<ConsentRoot state={resolveConsent()}> or a streamed TanStack Start loader,
it waits for the consent promise in its own Suspense boundary, so the
banner follows in a later chunk of the same response and shows before
hydration. Without a pending promise it renders its children as they are.
Call the hooks in a component inside it. Import it from
c15t/react/headless, c15t/next/headless or
c15t/tanstack-start/headless.

Add useConsentGate for custom consent gates

useConsentGate(category) returns what a gate on one consent category should
render: 'granted', 'pending', 'denied' or 'policy-blocked'. It also
returns the translated title, button label and policy message, and
requestConsent, which opens the preference center. Import it from
c15t/react/headless, c15t/next/headless or
c15t/tanstack-start/headless.

ConsentGate now runs on the hook, so a custom gate follows the same rules.
Granted content waits for hydration, a strict policy scope blocks categories
outside it, and server rendering never reads the clock. ConsentGate renders
the same markup as before.

Export banner copy and button labels for headless UIs

resolvePromptCopy(translations, prompt) returns the banner's title and
description, and reads the notice copy when the prompt is a notice.
resolveActionLabels(translations) labels each banner action, and
resolvePreferenceControlLabels(translations) labels the opt-out and
preferences buttons. All three use the active language and fall back to
English for a missing key. Import them from c15t, @c15t/svelte,
@c15t/svelte/headless, c15t/vue/vue-plugin or @c15t/browser/headless.
@c15t/browser/headless also exports resolveConsentPresentation now.

React adds useBannerCopy() and useConsentLabels() to
c15t/react/headless, c15t/next/headless and
c15t/tanstack-start/headless. They return the same strings the stock
banner renders and update when the language changes. The same headless
entries now export useVendorsListedUnder(category), which returns the
vendors the stock dialog lists under a category.

When a notice offers only a dismiss button, primaryActions from
resolveConsentPresentation now contains dismiss, so a headless banner can
style it as the primary button. The browser banner now styles that button as
primary too. The React, Vue and Svelte banners already did.

Allowed scripts start from the server HTML

Next.js, TanStack Start, Nuxt and SvelteKit now start the scripts entries a
visitor's consent already allows from the server-rendered HTML, before the page
hydrates. An inline script runs after first paint and inserts their tags; the
script loader adopts them. On a throttled mobile profile, vendors started about
800 ms sooner. This covers React 18 and 19, and every vendor helper in
@c15t/integrations except Cloudflare Zaraz and Sentry.

Nothing starts while the policy asks the visitor to choose, or from prerendered
or cached HTML. Set scriptLoader: { serverStart: false } to start every entry
after hydration, as before.

Rewrite npm descriptions for search

npm search scores a phrase in the description far above the same words in
keywords or the README. Each package description now names the phrases
people search for that package: "cookie banner", "cookie consent manager",
"consent management platform" and "Google Consent Mode v2" on c15t,
"React cookie banner" on @c15t/react, "Vue cookie consent" on @c15t/vue,
and so on. c15t keeps "The open standard for cookie banners". Supporting
packages describe their role in c15t instead of repeating the main
package's phrases. Keyword lists are shorter. No code changes.

v3.1.0

Compare Source

Get the provider's event dispatcher in every framework

Each framework now hands you one event dispatcher that sends to the provider's
registered scripts and reads consent when an event goes out:

  • useEventDispatcher() from c15t/react, c15t/next and
    c15t/tanstack-start
  • useEventDispatcher() from c15t/vue/vue-plugin, auto-imported in Nuxt
  • getEventDispatcher() from @c15t/svelte
  • getEventDispatcher() from c15t/astro/client
  • getEventDispatcher(runtime) from @c15t/browser

All dispatchers for one provider share a pageview history, so a consent change
or a remount no longer drops or resends a pageview, and an event sent right
after a visitor withdraws consent is dropped. Pass scripts to add more
destinations and pageviews to choose which integrations get single-page-app
pageviews. createEventDispatcher from @c15t/integrations/events still works
for code without a provider.

Clearer npm descriptions and keywords

Each package's npm description now says what it does in the words people
search for, such as cookie consent, cookie banner, GDPR, Google Consent Mode v2
and IAB TCF. Keywords add common search terms while preserving existing
framework, brand and integration terms. The schema and UI packages now link
to their directories in the repository. Framework, browser and core READMEs
now explain how consent policies handle GDPR and other privacy laws before
the setup instructions.

The preference dialog scrolls with your CSS

Visitors can scroll to every category and vendor in the preference dialog
again. Before this fix, the category list did not scroll with some app CSS.
The cause was overflow: hidden on the category list or on a category row,
for example to clip them to rounded corners. On a phone, a category with
vendors then went past the bottom of the dialog. The visitor could not scroll
to the rest.

Vendor switches show only when you declare vendors

The preference dialog shows only category switches until you declare a
vendor. Your visitors make one choice for each category. You do not get
vendor switches that you did not ask for.

Since 3.0.0, the dialog showed a switch for the vendor of each
@c15t/integrations helper. For example, a site that added only posthog()
got a PostHog switch under Analytics. We did not intend this default.

To show vendor switches, declare at least one vendor in the vendors option
or on the backend. The dialog then also lists the vendors of your helpers by
name, as before. This change affects only the dialog. It does not change when
a script loads.

Keep saved helper vendor denials accessible

A helper vendor the visitor previously switched off stays visible in the
preference dialog when the site declares no vendors. The visitor can turn that
vendor on without changing any category choices. Its saved denial continues to
block loading until the visitor changes it and saves. Other helper vendors stay
hidden until the site declares a vendor.

The browser dialog updates helper rows when saved vendor consent changes while
it is open.

v3.0.0

Compare Source

c15t v3

c15t v3 is stable and published under the latest tag. See the
3.0.0 changelog for new features, breaking
changes and upgrade guides.


Configuration

📅 Schedule: (in timezone Europe/Berlin)

  • Branch creation
    • Between 12:00 AM and 06:59 AM, only on Monday (* 0-6 * * 1)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@coderabbitai

coderabbitai Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 3518816d-e430-4287-860e-cc6c75ced733

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@renovate
renovate Bot force-pushed the renovate/c15t-nextjs-3.x branch 4 times, most recently from 5c04f84 to 2596abf Compare October 26, 2026 07:33
@renovate
renovate Bot force-pushed the renovate/c15t-nextjs-3.x branch 3 times, most recently from de43c5f to 859437f Compare November 4, 2026 20:49
@renovate
renovate Bot force-pushed the renovate/c15t-nextjs-3.x branch from 859437f to b026621 Compare November 7, 2026 14:58

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant