Initialization
This page covers installing the SDK, initializing it in your project, and the available configuration options.
Installation
- Web Elements
- React Elements
- npm
- yarn
- CDN
npm install --save @basis-theory/web-elements@beta
yarn add @basis-theory/web-elements@beta
1
After the script loads, window.BasisTheory is available as the factory function.
- npm
- yarn
npm install --save @basis-theory/react-elements@beta
yarn add @basis-theory/react-elements@beta
@basis-theory/web-elements separately — it is included as a dependency.Initialization
- Web Elements
- React Elements
ES module:
import BasisTheory from '@basis-theory/web-elements';
const bt = BasisTheory('<PUBLIC_API_KEY>');
const cardNumber = bt.createElement('cardNumber', {
placeholder: '4111 1111 1111 1111',
});
await cardNumber.mount('#card-number-container');
BasisTheory() is synchronous — it returns the SDK instance immediately with no await needed.
CDN / script tag:
1
<script>
document.addEventListener('DOMContentLoaded', async () => {
const bt = window.BasisTheory('<PUBLIC_API_KEY>');
const cardNumber = bt.createElement('cardNumber', {
placeholder: '4111 1111 1111 1111',
});
await cardNumber.mount('#card-number-container');
});
</script>
Wrap your application (or the subtree that uses elements) in BasisTheoryProvider. Pass your public API key via the apiKey prop.
import { BasisTheoryProvider, useBasisTheory } from '@basis-theory/react-elements';
function App() {
return (
<BasisTheoryProvider apiKey="<PUBLIC_API_KEY>">
<PaymentForm />
</BasisTheoryProvider>
);
}
function PaymentForm() {
const { bt } = useBasisTheory(); // reads SDK instance from context
// bt is null if initialization failed; check error from context if needed
if (!bt) return null;
return (/* your form */);
}
useBasisTheory() takes no arguments — it reads the SDK instance from the nearest BasisTheoryProvider.
SDK options
These options are passed as the second argument to BasisTheory(), or as the options prop on BasisTheoryProvider.
| Option | Type | Default | Description |
|---|---|---|---|
debug | boolean | false | Enable verbose debug logging to the browser console. |
themeMode | 'light' | 'dark' | 'auto' | 'auto' | Controls which theme tokens are applied. 'auto' follows the OS prefers-color-scheme. |
theme | ThemeTokens | — | Light-mode design tokens. See Theming. |
darkTheme | ThemeTokens | — | Dark-mode design tokens. If omitted and dark mode is active, falls back to theme. |
Framework-specific setup
Next.js
Elements require browser APIs and DOM access, so they must only be initialized on the client side. Mark any component that uses elements with "use client":
// components/PaymentForm.tsx
"use client";
import { useRef } from 'react';
import {
BasisTheoryProvider,
CardNumberElement,
ExpiryElement,
CVVElement,
useBasisTheory,
} from '@basis-theory/react-elements';
function PaymentFormInner() {
const { bt } = useBasisTheory();
const cardNumberRef = useRef(null);
const expiryRef = useRef(null);
const cvvRef = useRef(null);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const token = await bt!.tokens.create({
type: 'card',
data: {
number: cardNumberRef.current,
expiration_month: expiryRef.current,
expiration_year: expiryRef.current,
cvc: cvvRef.current,
},
});
console.log(token.id);
};
return (
<form onSubmit={handleSubmit}>
<CardNumberElement id="card-number" ref={cardNumberRef} />
<ExpiryElement id="expiry" ref={expiryRef} />
<CVVElement id="cvv" ref={cvvRef} />
<button type="submit">Pay</button>
</form>
);
}
export default function PaymentForm() {
return (
<BasisTheoryProvider apiKey={process.env.NEXT_PUBLIC_BASIS_THEORY_KEY!}>
<PaymentFormInner />
</BasisTheoryProvider>
);
}
Nuxt.js
Register Elements as a client-only plugin to prevent server-side rendering errors:
// plugins/basistheory.client.js
import BasisTheory from '@basis-theory/web-elements';
export default defineNuxtPlugin(() => {
const bt = BasisTheory(process.env.BASIS_PUBLIC_API_KEY);
return {
provide: { bt },
};
});
Then access the SDK in your components via useNuxtApp().$bt.
Don't see your framework? Reach out to support@basistheory.com and we'll help you integrate.
Best practices
- Single instance — Create one SDK instance and share it throughout your application rather than calling
BasisTheory()in multiple places. - Public keys only — Never use Private API keys in frontend code. Only
pk_keys belong in the browser. - CSP headers — If you use Content Security Policy, allow
frame-srcandscript-srcfor*.basistheory.com. See the security guide. - SRI for CDN usage — When loading the SDK via a CDN
<script>tag, add anintegrityattribute to verify the file has not been tampered with. See Subresource Integrity.