Web SDKs
Next.js
Client components for the browser and a server helper that uses your secret key.
@becklinks/next is the Beck Links package for Next.js, for the App Router and the Pages Router (Next.js 14 or newer). It has two entry points:
@becklinks/nextfor the browser: the provider, theuseCreateLinkhook and theSmartBannercomponent, already marked'use client'.@becklinks/next/serverfor your server code: create links with your secret key in Route Handlers, Server Actions and Server Components.
The browser part builds on @becklinks/web; read that page for the rules about keys, allowed websites and privacy.
Get it: @becklinks/next on npm
Install#
npm install @becklinks/nextAdd your site under Web origins in the environment settings (how).
Browser: provider and banner#
Create a small Client Component for the provider, then use it in the root layout:
// app/beck-links.tsx
'use client';
import { BeckLinksProvider, SmartBanner } from '@becklinks/next';
export function BeckLinks({ children }: { children: React.ReactNode }) {
return (
<BeckLinksProvider publishableKey={process.env.NEXT_PUBLIC_BECKLINKS_KEY ?? ''}>
<SmartBanner
url="https://acme.becklinks.com/summer"
title="Open in the Acme app"
description="Faster checkout and your saved items."
/>
{children}
</BeckLinksProvider>
);
}// app/layout.tsx
import { BeckLinks } from './beck-links';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<BeckLinks>{children}</BeckLinks>
</body>
</html>
);
}Put the publishable key in NEXT_PUBLIC_BECKLINKS_KEY. Anything with the NEXT_PUBLIC_ prefix is shipped to the browser, so never put a secret key there. The banner mounts after hydration, so server rendering is unchanged.
In Client Components, useCreateLink() creates links from the browser exactly as in React.
Server: create links with the secret key#
Browser-created links always use your environment's own host and a generated path. When you need a custom short path, a name, or want to create a link inside a trusted flow, do it on the server:
// app/api/share/route.ts
import { createServerBeckLinks } from '@becklinks/next/server';
const beckLinks = createServerBeckLinks(); // reads BECKLINKS_SECRET_KEY
export async function POST(request: Request) {
const { productId } = (await request.json()) as { productId: string };
const link = await beckLinks.createLink(
{
deepLinkPath: `/product/${productId}`,
path: `p-${productId}`,
name: `Product ${productId}`,
campaign: 'share-button',
},
{ idempotencyKey: `share-${productId}` },
);
return Response.json({ url: link.url });
}Set BECKLINKS_SECRET_KEY (sk_test_… or sk_live_…) in your server environment only. The helper refuses a publishable key, a malformed key and any run inside a browser. It calls POST /v1/links of the REST API and returns id, url, path, status, createdAt and expiresAt. Failures are BeckLinksError with the API's code, so you can branch on, for example, validation_failed or rate_limited.
Pass an idempotencyKey when your own code may retry: the same key returns the same link instead of creating a second one.
Verify it works#
- Run the app with a
pk_test_…key in.env.localandhttp://localhost:3000under Web origins of the Test environment. - In the browser's device mode set to a phone, the banner appears. On a desktop view it does not.
- Call your route:
curl -X POST http://localhost:3000/api/share -d '{"productId":"42"}'returns{"url":"https://…-test.becklinks.com/p-42"}. Run it again and you get the same URL. - The link is listed under Links in the dashboard. A
403 origin_not_allowedin the browser means the origin is not listed; see Web SDK errors.