Skip to main content

Svelte Customization

Customize

Pick the right tool

ChangeUse
Brand colors, radius, type, spacing--c15t-* variables in a stylesheet
One part of one componenttheme.slots on the provider
Button styles by actiontheme.consentActions
Shape, position, blocking, button orderConsentBanner props or presentation
Wording and languagesConsentBanner text props, or translations
Different markupHeadless

Customization explains how the pieces fit together across frameworks.

See the design gallery for five banner designs, from a bottom bar to a fully custom one, with tested code for this framework.

Set brand colors and radius

Write the --c15t-* variables on :root in a stylesheet. c15t's default tokens carry no specificity, so your rule replaces them wherever each loads:

src/consent-theme.css
/* Load after @c15t/svelte/styles.css so these values win. */
:root {
	--c15t-primary: #6943a3;
	--c15t-primary-hover: #533285;
	--c15t-text-on-primary: #ffffff;
	--c15t-radius-lg: 18px;
}
import './consent-theme.css';

Set a hover color and a text color with the primary color, so buttons stay readable in each state. Theme tokens lists every variable.

Do not put colors, radius or other tokens in the provider's theme prop. In the browser, theme applies slots and consentActions only; the token values are ignored. In development, the provider logs a warning when theme has tokens and the page has no <style id="c15t-theme">.

If your tokens come from data at runtime, generateThemeCSS(theme) from @c15t/ui/theme turns a theme object into the same CSS. Install @c15t/ui@alpha to use it, put the result in a <style id="c15t-theme"> element, and expect the generator to add to your bundle. Its selectors outrank the stock defaults, so the element works wherever it sits. They also outrank a plain :root rule of your own, so if you mix both, write your overrides on :root:root.

Switch to dark tokens

The provider's colorScheme prop switches on the dark token set: 'dark' always, 'system' when the operating system prefers dark, 'light' never. It toggles a c15t-dark class on <html>. Left unset, the provider copies a dark class on <html> into c15t-dark, so an app with its own dark mode toggle gets the dark tokens without the prop. Pass null if your app sets c15t-dark itself. Override dark values under :root.dark and :root.c15t-dark in your stylesheet. Dark mode covers a dark first paint.

Style one part with theme slots

The provider's theme prop still applies slot styles in the browser. A slot takes a class name, or { className, style, noStyle }. Svelte applies a slot's class and style on every stock part, including the IAB banner and dialog:

const theme = {
	slots: {
		consentBannerCard: 'brand-banner-card',
		consentBannerTitle: 'brand-banner-title',
	},
};

Pass it as theme={theme} on ConsentProvider. Define the class in a global stylesheet, or with :global(.brand-banner-card) in a component, because Svelte scopes component styles. The Svelte components read these slots:

ComponentSlots
ConsentBannerconsentBanner, consentBannerCard, consentBannerHeader, consentBannerTitle, consentBannerDescription, consentBannerFooter, consentBannerFooterSubGroup, consentBannerRights, consentBannerRightLink, consentBannerTag, consentBannerOverlay
ConsentDialogconsentDialog, consentDialogCard, consentDialogHeader, consentDialogTitle, consentDialogDescription, consentDialogContent, consentDialogTag
ConsentWidgetconsentWidget, consentWidgetFooter, consentWidgetFooterSubGroup, consentWidgetTag
ConsentDialogTriggerconsentDialogTrigger, consentDialogTriggerIcon
IABConsentBanneriabConsentBanner, iabConsentBannerTag, iabConsentBannerOverlay
ConsentGateconsentGate, consentGateTitle, consentGateButton
Buttons in every componentbuttonPrimary, buttonSecondary

Slot names are not React's components.banner.card keys; do not copy a React configuration. Use slots when one part should change and tokens when a value should change everywhere. class on a component, such as <ConsentBanner class="...">, goes on its root. Component parts explains the attributes each element carries, and Tailwind CSS shows the Svelte and SvelteKit setups for Tailwind 4 and 3.

Change button styles by action

theme.consentActions picks each button's style by what it does, whichever order the policy puts the buttons in:

const theme = {
	consentActions: {
		default: { variant: 'neutral', mode: 'stroke' },
		primary: { variant: 'primary', mode: 'filled' },
		reject: { variant: 'neutral', mode: 'filled' },
	},
};

A per-action entry overrides primary, which overrides default. The policy decides which action is primary.

Change the banner shape and position

Set the shape on the banner itself, or for every surface with the provider's presentation prop:

<ConsentBanner variant="bar" position="bottom" />
variantPositions
floatingbottom-left (default), bottom-right, top-left, top-right, bottom-center, top-center
barbottom (default), top
widgetbottom-right (default), bottom-left, top-left, top-right
wallcenter

blocking adds a backdrop, locks scrolling, traps focus and stops outside clicks from closing the banner. layout and primaryButton change the button order and emphasis. The policy wins where they conflict. A policy that requires a reject button keeps it, whatever the layout says.

Change the copy

For one banner, the text props on ConsentBanner, such as title and rejectButtonText, replace the copy in every mode:

<ConsentBanner title="Your privacy" rejectButtonText="Reject optional" />

For site-wide copy, pass the provider's i18n messages. In offline() mode they merge over the bundled English copy. In hosted() mode they merge over the backend's copy for the same language, key by key, so keys you leave out keep the wording from your Inth project. Translations covers both, the message keys and switching languages. Copy and translations covers wording for each action.

Turn off animations

disableAnimation on the provider turns off the banner and dialog animations, and the same prop on ConsentBanner, ConsentDialog, IABConsentBanner or IABConsentDialog overrides it for one surface. Left unset, the provider follows the visitor's reduced motion setting. Motion and animation covers the duration and easing tokens.

Remove c15t's styles

Set noStyle on one component or on the provider to render the same markup and behavior without c15t's classes. Style the data-* attributes and your slot classes instead. For different markup, see the headless page.