
Security News
rv Is a New Rust-Powered Ruby Version Manager Inspired by Python's uv
Ruby maintainers from Bundler and rbenv teams are building rv to bring Python uv's speed and unified tooling approach to Ruby development.
@cardql/react
Advanced tools
CardQL SDK for React web applications with hooks and context providers
CardQL SDK for React web applications with hooks, context providers, and pre-built components.
npm install @cardql/react
# or
yarn add @cardql/react
# or
pnpm add @cardql/react
Wrap your app with the CardQL provider:
import React from "react";
import { CardQLProvider } from "@cardql/react";
function App() {
return (
<CardQLProvider
config={{
apiKey: "your-api-key",
endpoint: "https://api.cardql.com/graphql",
}}>
<YourApp />
</CardQLProvider>
);
}
Use CardQL hooks in your components:
import React from "react";
import { usePayments, useCreatePayment } from "@cardql/react";
function PaymentList() {
const { data: paymentsData, loading, error } = usePayments();
const createPayment = useCreatePayment({
onSuccess: (data) => {
console.log("Payment created:", data.createPayment);
},
});
const handleCreatePayment = async () => {
await createPayment.mutateAsync({
amount: "10.00",
currency: "USD",
merchantID: "merchant_123",
userID: "user_456",
});
};
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
<h2>Payments</h2>
<button onClick={handleCreatePayment} disabled={createPayment.loading}>
{createPayment.loading ? "Creating..." : "Create Payment"}
</button>
{paymentsData?.payments.map((payment) => (
<div key={payment.id}>
{payment.amount} {payment.currency} - {payment.status}
</div>
))}
</div>
);
}
Use ready-made components:
import React from "react";
import { PaymentForm } from "@cardql/react";
function CheckoutPage() {
return (
<div>
<h1>Checkout</h1>
<PaymentForm
merchantID="merchant_123"
userID="user_456"
onSuccess={(payment) => {
console.log("Payment successful:", payment);
// Redirect to success page
}}
onError={(error) => {
console.error("Payment failed:", error);
// Show error message
}}
/>
</div>
);
}
interface CardQLProviderProps {
config: CardQLConfig;
children: ReactNode;
}
<CardQLProvider config={{ apiKey: "...", endpoint: "..." }}>
<App />
</CardQLProvider>;
Access the CardQL context:
const { cardql, config } = useCardQL();
Get the CardQL client directly:
const cardql = useCardQLClient();
Get the CardQL API directly:
const api = useCardQLApi();
Generic hook for GraphQL queries:
const { data, loading, error, refetch } = useQuery(
"query GetPayments { payments { id amount status } }",
variables,
{
enabled: true,
refetchOnMount: true,
refetchInterval: 30000,
onSuccess: (data) => console.log(data),
onError: (error) => console.error(error),
}
);
Generic hook for GraphQL mutations:
const { data, loading, error, mutate, mutateAsync } = useMutation(
"mutation CreatePayment($input: CreatePaymentInput!) { createPayment(input: $input) { id } }",
{
onSuccess: (data, variables) => console.log("Success:", data),
onError: (error, variables) => console.error("Error:", error),
onSettled: (data, error, variables) => console.log("Settled"),
}
);
// Query hooks
const { data, loading, error } = useAccounts();
const { data, loading, error } = useAccount(accountID);
// Mutation hooks
const createAccount = useCreateAccount();
const updateAccount = useUpdateAccount();
const deleteAccount = useDeleteAccount();
// Query hooks
const { data, loading, error } = useCustomers();
const { data, loading, error } = useCustomer(customerID);
// Mutation hooks
const createCustomer = useCreateCustomer({
onSuccess: (data) => {
console.log("Customer created:", data.createCustomer);
},
});
// Usage
await createCustomer.mutateAsync({
firstName: "John",
lastName: "Doe",
email: "john@example.com",
});
// Query hooks
const { data, loading, error } = usePayments();
const { data, loading, error } = usePayment(paymentID);
// Mutation hooks
const createPayment = useCreatePayment();
const updatePayment = useUpdatePayment();
const deletePayment = useDeletePayment();
// Usage
const handlePayment = async () => {
try {
const result = await createPayment.mutateAsync({
amount: "25.99",
currency: "USD",
merchantID: "merchant_123",
userID: "user_456",
description: "Product purchase",
});
console.log("Payment created:", result.createPayment);
} catch (error) {
console.error("Payment failed:", error);
}
};
const { data, loading, error } = useMerchants();
const { data, loading, error } = useMerchant(merchantID);
const createMerchant = useCreateMerchant();
const updateMerchant = useUpdateMerchant();
const deleteMerchant = useDeleteMerchant();
const { data, loading, error } = useLedgers();
const { data, loading, error } = useLedger(ledgerID);
const createLedger = useCreateLedger();
const updateLedger = useUpdateLedger();
const deleteLedger = useDeleteLedger();
Pre-built payment form component:
<PaymentForm
merchantID="merchant_123"
userID="user_456"
onSuccess={(payment) => {
// Handle successful payment
router.push("/success");
}}
onError={(error) => {
// Handle payment error
setErrorMessage(error.message);
}}
className="custom-payment-form"
disabled={false}
/>
Execute custom GraphQL queries:
import { useQuery } from "@cardql/react";
function CustomPaymentList() {
const { data, loading, error } = useQuery(
`
query GetPaymentsByMerchant($merchantID: String!) {
payments(where: { merchantID: $merchantID }) {
id
amount
currency
status
customer {
firstName
lastName
}
}
}
`,
{
merchantID: "merchant_123",
}
);
// ... render logic
}
// Poll every 30 seconds
const { data } = usePayments({
refetchInterval: 30000,
});
// Manual refetch
const { data, refetch } = usePayments();
const handleRefresh = () => {
refetch();
};
import { usePayments, useCreatePayment } from "@cardql/react";
function PaymentComponent() {
const { data, loading, error } = usePayments({
onError: (error) => {
console.error("Failed to load payments:", error);
// Send to error tracking service
},
});
const createPayment = useCreatePayment({
onError: (error, variables) => {
console.error("Payment creation failed:", error);
// Show user-friendly error message
if (error.code === "INSUFFICIENT_FUNDS") {
alert("Insufficient funds");
} else {
alert("Payment failed. Please try again.");
}
},
});
// ... component logic
}
function PaymentList() {
const { data, loading, error } = usePayments();
const createPayment = useCreatePayment();
if (loading) {
return <PaymentSkeleton />;
}
if (error) {
return <ErrorMessage error={error} />;
}
return (
<div>
<button
onClick={() => createPayment.mutate(paymentData)}
disabled={createPayment.loading}>
{createPayment.loading ? <Spinner /> : "Create Payment"}
</button>
{/* Payment list */}
</div>
);
}
import { useForm } from "react-hook-form";
import { useCreateCustomer } from "@cardql/react";
function CustomerForm() {
const { register, handleSubmit, reset } = useForm();
const createCustomer = useCreateCustomer({
onSuccess: () => {
reset(); // Clear form on success
},
});
const onSubmit = async (data) => {
await createCustomer.mutateAsync(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("firstName")} placeholder="First Name" />
<input {...register("lastName")} placeholder="Last Name" />
<input {...register("email")} placeholder="Email" />
<button type="submit" disabled={createCustomer.loading}>
{createCustomer.loading ? "Creating..." : "Create Customer"}
</button>
</form>
);
}
The React SDK is fully typed:
import type { Payment, CreatePaymentInput } from "@cardql/react";
const createPayment = useCreatePayment();
// TypeScript knows the exact shape of the data
const handleSubmit = async (input: CreatePaymentInput) => {
const result = await createPayment.mutateAsync(input);
// result.createPayment is typed as Payment
console.log(result.createPayment.id);
};
The pre-built components use CSS classes that you can style:
.cardql-payment-form {
max-width: 400px;
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
}
.cardql-form-field {
margin-bottom: 16px;
}
.cardql-form-field label {
display: block;
margin-bottom: 4px;
font-weight: 500;
}
.cardql-form-field input,
.cardql-form-field select {
width: 100%;
padding: 8px 12px;
border: 1px solid #ccc;
border-radius: 4px;
}
.cardql-error {
color: #dc3545;
margin-bottom: 16px;
padding: 8px;
background-color: #f8d7da;
border-radius: 4px;
}
.cardql-submit-button {
width: 100%;
padding: 12px;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.cardql-submit-button:disabled {
background-color: #6c757d;
cursor: not-allowed;
}
Place the CardQL provider at the highest level where you need CardQL functionality:
// ✅ Good - wrap entire app
function App() {
return (
<CardQLProvider config={config}>
<Router>
<Routes>
<Route path="/payments" component={PaymentPage} />
<Route path="/customers" component={CustomerPage} />
</Routes>
</Router>
</CardQLProvider>
);
}
Use error boundaries to catch and handle errors:
import { ErrorBoundary } from "react-error-boundary";
function ErrorFallback({ error, resetErrorBoundary }) {
return (
<div role="alert">
<h2>Something went wrong:</h2>
<pre>{error.message}</pre>
<button onClick={resetErrorBoundary}>Try again</button>
</div>
);
}
function App() {
return (
<CardQLProvider config={config}>
<ErrorBoundary FallbackComponent={ErrorFallback}>
<YourApp />
</ErrorBoundary>
</CardQLProvider>
);
}
Always handle loading states for better UX:
function PaymentList() {
const { data, loading, error } = usePayments();
if (loading) return <PaymentSkeleton />;
if (error) return <ErrorMessage error={error} />;
if (!data?.payments.length) return <EmptyState />;
return <PaymentGrid payments={data.payments} />;
}
MIT
For support, please contact the CardQL team or visit our documentation.
FAQs
CardQL SDK for React web applications with hooks and context providers
We found that @cardql/react demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Ruby maintainers from Bundler and rbenv teams are building rv to bring Python uv's speed and unified tooling approach to Ruby development.
Security News
Following last week’s supply chain attack, Nx published findings on the GitHub Actions exploit and moved npm publishing to Trusted Publishers.
Security News
AGENTS.md is a fast-growing open format giving AI coding agents a shared, predictable way to understand project setup, style, and workflows.