@quikturn/logos-next 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,262 @@
1
+ # @quikturn/logos-next
2
+
3
+ > Next.js components for the [Quikturn Logos API](https://getquikturn.io) -- `<QuikturnImage>` with `next/image` integration, image loaders, and server helpers.
4
+
5
+ **[Get your API key](https://getquikturn.io)** -- free tier available, no credit card required.
6
+
7
+ ## Features
8
+
9
+ - **`<QuikturnImage>`** -- `next/image` wrapper that renders a Quikturn logo with automatic optimization
10
+ - **`quikturnImageLoader`** -- basic Next.js image loader for the Logos API
11
+ - **`createQuikturnImageLoader()`** -- factory for pre-configured image loaders with token, format, theme
12
+ - **`<QuikturnProvider>`** -- context provider for token and base URL propagation
13
+ - **Server helpers** -- `getServerClient()` and `getLogoBuffer()` for API routes and server components
14
+ - **Re-exports** -- all `@quikturn/logos-react` components (`QuikturnLogo`, `QuikturnLogoCarousel`, `QuikturnLogoGrid`, `useLogoUrl`)
15
+ - **Tree-shakeable** -- ESM and CJS dual builds; import only what you use
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ # pnpm (recommended)
21
+ pnpm add @quikturn/logos-next @quikturn/logos @quikturn/logos-react next react react-dom
22
+
23
+ # npm
24
+ npm install @quikturn/logos-next @quikturn/logos @quikturn/logos-react next react react-dom
25
+ ```
26
+
27
+ **Peer dependencies:** `next >= 14`, `react >= 18`, `react-dom >= 18`
28
+
29
+ ## Quick Start
30
+
31
+ ```tsx
32
+ import { QuikturnProvider, QuikturnImage } from "@quikturn/logos-next";
33
+
34
+ export default function Page() {
35
+ return (
36
+ <QuikturnProvider token="qt_your_publishable_key">
37
+ <QuikturnImage domain="github.com" width={128} height={128} alt="GitHub" />
38
+ </QuikturnProvider>
39
+ );
40
+ }
41
+ ```
42
+
43
+ ## API Reference
44
+
45
+ ### `<QuikturnImage>`
46
+
47
+ A `next/image` wrapper that renders a Quikturn logo for the given domain. Automatically constructs a custom `loader`, fires an attribution beacon on mount, and reads a token from `<QuikturnProvider>` context when available.
48
+
49
+ ```tsx
50
+ <QuikturnImage
51
+ domain="stripe.com"
52
+ width={256}
53
+ height={256}
54
+ format="webp"
55
+ greyscale
56
+ theme="dark"
57
+ alt="Stripe"
58
+ priority
59
+ />
60
+ ```
61
+
62
+ | Prop | Type | Default | Description |
63
+ |------|------|---------|-------------|
64
+ | `domain` | `string` | **required** | Domain to fetch logo for |
65
+ | `token` | `string` | from context | Publishable API key (`qt_`/`pk_` prefix) |
66
+ | `format` | `string` | -- | Output format (`"png"`, `"jpeg"`, `"webp"`, `"avif"`, or MIME type) |
67
+ | `greyscale` | `boolean` | `false` | Greyscale transformation |
68
+ | `theme` | `"light" \| "dark"` | -- | Background-optimized rendering |
69
+ | `width` | `number` | **required** | Image width in pixels (from `next/image`) |
70
+ | `height` | `number` | **required** | Image height in pixels (from `next/image`) |
71
+ | `alt` | `string` | `"<domain> logo"` | Image alt text |
72
+ | `priority` | `boolean` | `false` | Disable lazy loading (from `next/image`) |
73
+ | ...rest | `ImageProps` | -- | All other `next/image` props are forwarded |
74
+
75
+ ---
76
+
77
+ ### `quikturnImageLoader`
78
+
79
+ Basic image loader compatible with `next/image`. Converts a domain + width into a Logos API URL without any pre-configured options.
80
+
81
+ ```tsx
82
+ import Image from "next/image";
83
+ import { quikturnImageLoader } from "@quikturn/logos-next";
84
+
85
+ <Image
86
+ loader={quikturnImageLoader}
87
+ src="github.com"
88
+ width={256}
89
+ height={256}
90
+ alt="GitHub"
91
+ />
92
+ ```
93
+
94
+ ---
95
+
96
+ ### `createQuikturnImageLoader(options)`
97
+
98
+ Factory that creates a pre-configured image loader with baked-in token, format, theme, and other options.
99
+
100
+ ```tsx
101
+ import Image from "next/image";
102
+ import { createQuikturnImageLoader } from "@quikturn/logos-next";
103
+
104
+ const loader = createQuikturnImageLoader({
105
+ token: "qt_abc123",
106
+ format: "webp",
107
+ greyscale: true,
108
+ });
109
+
110
+ <Image loader={loader} src="github.com" width={256} height={256} alt="GitHub" />
111
+ ```
112
+
113
+ | Option | Type | Description |
114
+ |--------|------|-------------|
115
+ | `token` | `string` | Publishable API key |
116
+ | `format` | `string` | Output format |
117
+ | `greyscale` | `boolean` | Greyscale transformation |
118
+ | `theme` | `"light" \| "dark"` | Theme optimization |
119
+ | `baseUrl` | `string` | Override the Quikturn API base URL |
120
+
121
+ ---
122
+
123
+ ### `<QuikturnProvider>`
124
+
125
+ Provides `token` and `baseUrl` to all nested `QuikturnImage` components via React Context.
126
+
127
+ ```tsx
128
+ <QuikturnProvider token="qt_abc123" baseUrl="https://custom.api">
129
+ {children}
130
+ </QuikturnProvider>
131
+ ```
132
+
133
+ | Prop | Type | Required | Description |
134
+ |------|------|----------|-------------|
135
+ | `token` | `string` | yes | Publishable API key (`qt_`/`pk_` prefix) |
136
+ | `baseUrl` | `string` | no | Override the Quikturn API base URL |
137
+ | `children` | `ReactNode` | yes | Child components |
138
+
139
+ ---
140
+
141
+ ### Server Helpers
142
+
143
+ Import from `@quikturn/logos-next/server` for use in API routes and server components. This entry point is gated by `server-only` and will throw at build time if imported in client code.
144
+
145
+ #### `getServerClient()`
146
+
147
+ Returns a singleton `QuikturnLogos` server client. Reads the `QUIKTURN_SECRET_KEY` environment variable on first call and caches the instance.
148
+
149
+ #### `getLogoBuffer(domain, options?)`
150
+
151
+ Convenience wrapper that fetches a logo buffer using the cached server client.
152
+
153
+ ```ts
154
+ // app/api/logo/route.ts
155
+ import { getLogoBuffer } from "@quikturn/logos-next/server";
156
+
157
+ export async function GET(request: Request) {
158
+ const { searchParams } = new URL(request.url);
159
+ const domain = searchParams.get("domain") ?? "example.com";
160
+
161
+ const result = await getLogoBuffer(domain, { format: "image/webp" });
162
+
163
+ return new Response(result.buffer, {
164
+ headers: { "Content-Type": result.contentType },
165
+ });
166
+ }
167
+ ```
168
+
169
+ **Environment variable required:** `QUIKTURN_SECRET_KEY` (set in `.env.local` or your deployment environment).
170
+
171
+ ---
172
+
173
+ ## Re-exported Components
174
+
175
+ The following are re-exported from `@quikturn/logos-react` for convenience, so you can import everything from a single package:
176
+
177
+ - **`<QuikturnLogo>`** -- single logo image with lazy loading and optional link wrapper
178
+ - **`<QuikturnLogoCarousel>`** -- infinite scrolling logo ticker
179
+ - **`<QuikturnLogoGrid>`** -- responsive CSS grid of logos
180
+ - **`useLogoUrl()`** -- hook that returns a memoized Quikturn logo URL
181
+
182
+ See the [@quikturn/logos-react README](https://www.npmjs.com/package/@quikturn/logos-react) for full documentation on these components.
183
+
184
+ ---
185
+
186
+ ## Examples
187
+
188
+ ### Logo Grid with Next.js Image Optimization
189
+
190
+ ```tsx
191
+ import { QuikturnProvider, QuikturnImage } from "@quikturn/logos-next";
192
+
193
+ const PARTNERS = ["github.com", "stripe.com", "vercel.com", "figma.com"];
194
+
195
+ export default function Partners() {
196
+ return (
197
+ <QuikturnProvider token="qt_your_key">
198
+ <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 24 }}>
199
+ {PARTNERS.map((domain) => (
200
+ <QuikturnImage key={domain} domain={domain} width={128} height={128} alt={domain} />
201
+ ))}
202
+ </div>
203
+ </QuikturnProvider>
204
+ );
205
+ }
206
+ ```
207
+
208
+ ### Custom Loader with Global Config
209
+
210
+ ```tsx
211
+ // lib/quikturn-loader.ts
212
+ import { createQuikturnImageLoader } from "@quikturn/logos-next";
213
+
214
+ export const logoLoader = createQuikturnImageLoader({
215
+ token: process.env.NEXT_PUBLIC_QUIKTURN_KEY!,
216
+ format: "webp",
217
+ });
218
+
219
+ // app/page.tsx
220
+ import Image from "next/image";
221
+ import { logoLoader } from "@/lib/quikturn-loader";
222
+
223
+ export default function Page() {
224
+ return <Image loader={logoLoader} src="github.com" width={64} height={64} alt="GitHub" />;
225
+ }
226
+ ```
227
+
228
+ ### Server-Side Logo Proxy
229
+
230
+ ```ts
231
+ // app/api/logo/[domain]/route.ts
232
+ import { getLogoBuffer } from "@quikturn/logos-next/server";
233
+
234
+ export async function GET(
235
+ _request: Request,
236
+ { params }: { params: { domain: string } },
237
+ ) {
238
+ const result = await getLogoBuffer(params.domain, {
239
+ format: "image/png",
240
+ size: 256,
241
+ });
242
+
243
+ return new Response(result.buffer, {
244
+ headers: {
245
+ "Content-Type": result.contentType,
246
+ "Cache-Control": "public, max-age=86400",
247
+ },
248
+ });
249
+ }
250
+ ```
251
+
252
+ ## Resources
253
+
254
+ - **[Quikturn website](https://getquikturn.io)** -- sign up, manage keys, explore the API
255
+ - **[Dashboard](https://getquikturn.io/dashboard)** -- usage analytics, key management, plan upgrades
256
+ - **[Pricing](https://getquikturn.io/pricing)** -- free tier, pro, and enterprise plans
257
+ - **[Core SDK docs](https://www.npmjs.com/package/@quikturn/logos)** -- `@quikturn/logos` URL builder, browser client, server client
258
+ - **[React SDK docs](https://www.npmjs.com/package/@quikturn/logos-react)** -- `@quikturn/logos-react` components and hooks
259
+
260
+ ## License
261
+
262
+ MIT -- built by [Quikturn](https://getquikturn.io)
package/dist/index.cjs ADDED
@@ -0,0 +1,101 @@
1
+ 'use strict';
2
+
3
+ var Image2 = require('next/image');
4
+ var logos = require('@quikturn/logos');
5
+ var react = require('react');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+ var logosReact = require('@quikturn/logos-react');
8
+
9
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
+
11
+ var Image2__default = /*#__PURE__*/_interopDefault(Image2);
12
+
13
+ var fired = /* @__PURE__ */ new Set();
14
+ function fireBeacon(token) {
15
+ if (typeof window === "undefined") return;
16
+ if (!token || token.startsWith("sk_")) return;
17
+ if (fired.has(token)) return;
18
+ fired.add(token);
19
+ const img = new Image();
20
+ img.src = `${logos.BASE_URL}/_beacon?token=${token}&page=${encodeURIComponent(location.href)}`;
21
+ }
22
+ var QuikturnContext = react.createContext(null);
23
+ function useQuikturnContext() {
24
+ return react.useContext(QuikturnContext);
25
+ }
26
+ function QuikturnProvider({
27
+ token,
28
+ baseUrl,
29
+ children
30
+ }) {
31
+ return /* @__PURE__ */ jsxRuntime.jsx(QuikturnContext.Provider, { value: { token, baseUrl }, children });
32
+ }
33
+ function QuikturnImage({
34
+ domain,
35
+ token,
36
+ format,
37
+ greyscale,
38
+ theme,
39
+ alt,
40
+ ...imageProps
41
+ }) {
42
+ const ctx = useQuikturnContext();
43
+ const effectiveToken = token ?? ctx?.token ?? "";
44
+ const loader = react.useMemo(
45
+ () => ({ src, width }) => logos.logoUrl(src, {
46
+ token: effectiveToken || void 0,
47
+ size: width,
48
+ format,
49
+ greyscale,
50
+ theme
51
+ }),
52
+ [effectiveToken, format, greyscale, theme]
53
+ );
54
+ react.useEffect(() => {
55
+ if (effectiveToken) fireBeacon(effectiveToken);
56
+ }, [effectiveToken]);
57
+ return /* @__PURE__ */ jsxRuntime.jsx(
58
+ Image2__default.default,
59
+ {
60
+ ...imageProps,
61
+ src: domain,
62
+ loader,
63
+ alt: alt ?? `${domain} logo`
64
+ }
65
+ );
66
+ }
67
+ function quikturnImageLoader({ src, width }) {
68
+ return logos.logoUrl(src, { size: width });
69
+ }
70
+ function createQuikturnImageLoader(options) {
71
+ return ({ src, width }) => logos.logoUrl(src, {
72
+ token: options.token,
73
+ size: width,
74
+ format: options.format,
75
+ greyscale: options.greyscale,
76
+ theme: options.theme,
77
+ baseUrl: options.baseUrl
78
+ });
79
+ }
80
+
81
+ Object.defineProperty(exports, "QuikturnLogo", {
82
+ enumerable: true,
83
+ get: function () { return logosReact.QuikturnLogo; }
84
+ });
85
+ Object.defineProperty(exports, "QuikturnLogoCarousel", {
86
+ enumerable: true,
87
+ get: function () { return logosReact.QuikturnLogoCarousel; }
88
+ });
89
+ Object.defineProperty(exports, "QuikturnLogoGrid", {
90
+ enumerable: true,
91
+ get: function () { return logosReact.QuikturnLogoGrid; }
92
+ });
93
+ Object.defineProperty(exports, "useLogoUrl", {
94
+ enumerable: true,
95
+ get: function () { return logosReact.useLogoUrl; }
96
+ });
97
+ exports.QuikturnImage = QuikturnImage;
98
+ exports.QuikturnProvider = QuikturnProvider;
99
+ exports.createQuikturnImageLoader = createQuikturnImageLoader;
100
+ exports.quikturnImageLoader = quikturnImageLoader;
101
+ exports.useQuikturnContext = useQuikturnContext;
@@ -0,0 +1,115 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ImageProps } from 'next/image';
3
+ import { LogoRequestOptions } from '@quikturn/logos';
4
+ export { LogoConfig, LogoOptions, QuikturnLogo, QuikturnLogoCarousel, QuikturnLogoCarouselProps, QuikturnLogoGrid, QuikturnLogoGridProps, QuikturnLogoProps, ResolvedLogo, useLogoUrl } from '@quikturn/logos-react';
5
+
6
+ /**
7
+ * Props accepted by the `QuikturnImage` component.
8
+ *
9
+ * Extends all `next/image` props except `src` and `loader` (which are
10
+ * derived from the `domain` and logo-specific options).
11
+ */
12
+ interface QuikturnImageProps extends Omit<ImageProps, "src" | "loader"> {
13
+ /** The domain to fetch a logo for (e.g. "github.com"). */
14
+ domain: string;
15
+ /** Publishable API token (qt_ / pk_ prefix). Overrides context token. */
16
+ token?: string;
17
+ /** Output image format. */
18
+ format?: LogoRequestOptions["format"];
19
+ /** When true, returns a greyscale logo. */
20
+ greyscale?: boolean;
21
+ /** Theme adjustment ("light" or "dark"). */
22
+ theme?: LogoRequestOptions["theme"];
23
+ }
24
+ /**
25
+ * Next.js `<Image>` wrapper that renders a Quikturn logo for the given domain.
26
+ *
27
+ * Automatically constructs a custom `loader` using `logoUrl()` from
28
+ * `@quikturn/logos`, fires an attribution beacon on mount, and supports
29
+ * reading a token from `<QuikturnProvider>` context.
30
+ *
31
+ * @example
32
+ * ```tsx
33
+ * <QuikturnImage domain="github.com" token="qt_abc" width={128} height={128} alt="GitHub" />
34
+ * ```
35
+ */
36
+ declare function QuikturnImage({ domain, token, format, greyscale, theme, alt, ...imageProps }: QuikturnImageProps): react_jsx_runtime.JSX.Element;
37
+
38
+ /**
39
+ * Props matching the Next.js `ImageLoaderProps` interface from `next/image`.
40
+ *
41
+ * - `src` - The domain string (or image source) passed by Next.js.
42
+ * - `width` - The resolved width in pixels requested by Next.js.
43
+ * - `quality` - Optional quality hint (unused by the Logos API, included for compatibility).
44
+ */
45
+ interface ImageLoaderProps {
46
+ src: string;
47
+ width: number;
48
+ quality?: number;
49
+ }
50
+ /**
51
+ * Options for configuring a Quikturn image loader factory.
52
+ *
53
+ * These options are "baked in" to the returned loader function so they
54
+ * don't need to be supplied on every call.
55
+ */
56
+ interface QuikturnImageLoaderOptions {
57
+ token?: string;
58
+ format?: LogoRequestOptions["format"];
59
+ greyscale?: boolean;
60
+ theme?: LogoRequestOptions["theme"];
61
+ baseUrl?: string;
62
+ }
63
+ /**
64
+ * Basic Quikturn image loader compatible with Next.js `next/image`.
65
+ *
66
+ * Converts a domain + width into a Logos API URL. Does not inject a token
67
+ * or any additional options -- use {@link createQuikturnImageLoader} for that.
68
+ *
69
+ * @example
70
+ * ```tsx
71
+ * import Image from "next/image";
72
+ * import { quikturnImageLoader } from "@quikturn/logos-next";
73
+ *
74
+ * <Image loader={quikturnImageLoader} src="github.com" width={256} height={256} alt="GitHub" />
75
+ * ```
76
+ */
77
+ declare function quikturnImageLoader({ src, width }: ImageLoaderProps): string;
78
+ /**
79
+ * Factory that creates a Quikturn image loader with pre-configured options.
80
+ *
81
+ * The returned function is compatible with Next.js `next/image`'s `loader` prop.
82
+ * Options such as `token`, `format`, `greyscale`, `theme`, and `baseUrl` are
83
+ * captured in the closure so they apply to every call automatically.
84
+ *
85
+ * @example
86
+ * ```tsx
87
+ * import Image from "next/image";
88
+ * import { createQuikturnImageLoader } from "@quikturn/logos-next";
89
+ *
90
+ * const loader = createQuikturnImageLoader({ token: "qt_abc123", format: "webp" });
91
+ *
92
+ * <Image loader={loader} src="github.com" width={256} height={256} alt="GitHub" />
93
+ * ```
94
+ */
95
+ declare function createQuikturnImageLoader(options: QuikturnImageLoaderOptions): (props: ImageLoaderProps) => string;
96
+
97
+ interface QuikturnContextValue {
98
+ token: string;
99
+ baseUrl?: string;
100
+ }
101
+ /** Read the current Quikturn context (token + optional baseUrl). */
102
+ declare function useQuikturnContext(): QuikturnContextValue | null;
103
+ /** Props for the QuikturnProvider component. */
104
+ interface QuikturnProviderProps {
105
+ token: string;
106
+ baseUrl?: string;
107
+ children: React.ReactNode;
108
+ }
109
+ /**
110
+ * Provides a Quikturn token (and optional baseUrl) to all descendant
111
+ * `QuikturnImage` components so they don't need an explicit `token` prop.
112
+ */
113
+ declare function QuikturnProvider({ token, baseUrl, children, }: QuikturnProviderProps): react_jsx_runtime.JSX.Element;
114
+
115
+ export { type ImageLoaderProps, QuikturnImage, type QuikturnImageLoaderOptions, type QuikturnImageProps, QuikturnProvider, createQuikturnImageLoader, quikturnImageLoader, useQuikturnContext };
@@ -0,0 +1,115 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ImageProps } from 'next/image';
3
+ import { LogoRequestOptions } from '@quikturn/logos';
4
+ export { LogoConfig, LogoOptions, QuikturnLogo, QuikturnLogoCarousel, QuikturnLogoCarouselProps, QuikturnLogoGrid, QuikturnLogoGridProps, QuikturnLogoProps, ResolvedLogo, useLogoUrl } from '@quikturn/logos-react';
5
+
6
+ /**
7
+ * Props accepted by the `QuikturnImage` component.
8
+ *
9
+ * Extends all `next/image` props except `src` and `loader` (which are
10
+ * derived from the `domain` and logo-specific options).
11
+ */
12
+ interface QuikturnImageProps extends Omit<ImageProps, "src" | "loader"> {
13
+ /** The domain to fetch a logo for (e.g. "github.com"). */
14
+ domain: string;
15
+ /** Publishable API token (qt_ / pk_ prefix). Overrides context token. */
16
+ token?: string;
17
+ /** Output image format. */
18
+ format?: LogoRequestOptions["format"];
19
+ /** When true, returns a greyscale logo. */
20
+ greyscale?: boolean;
21
+ /** Theme adjustment ("light" or "dark"). */
22
+ theme?: LogoRequestOptions["theme"];
23
+ }
24
+ /**
25
+ * Next.js `<Image>` wrapper that renders a Quikturn logo for the given domain.
26
+ *
27
+ * Automatically constructs a custom `loader` using `logoUrl()` from
28
+ * `@quikturn/logos`, fires an attribution beacon on mount, and supports
29
+ * reading a token from `<QuikturnProvider>` context.
30
+ *
31
+ * @example
32
+ * ```tsx
33
+ * <QuikturnImage domain="github.com" token="qt_abc" width={128} height={128} alt="GitHub" />
34
+ * ```
35
+ */
36
+ declare function QuikturnImage({ domain, token, format, greyscale, theme, alt, ...imageProps }: QuikturnImageProps): react_jsx_runtime.JSX.Element;
37
+
38
+ /**
39
+ * Props matching the Next.js `ImageLoaderProps` interface from `next/image`.
40
+ *
41
+ * - `src` - The domain string (or image source) passed by Next.js.
42
+ * - `width` - The resolved width in pixels requested by Next.js.
43
+ * - `quality` - Optional quality hint (unused by the Logos API, included for compatibility).
44
+ */
45
+ interface ImageLoaderProps {
46
+ src: string;
47
+ width: number;
48
+ quality?: number;
49
+ }
50
+ /**
51
+ * Options for configuring a Quikturn image loader factory.
52
+ *
53
+ * These options are "baked in" to the returned loader function so they
54
+ * don't need to be supplied on every call.
55
+ */
56
+ interface QuikturnImageLoaderOptions {
57
+ token?: string;
58
+ format?: LogoRequestOptions["format"];
59
+ greyscale?: boolean;
60
+ theme?: LogoRequestOptions["theme"];
61
+ baseUrl?: string;
62
+ }
63
+ /**
64
+ * Basic Quikturn image loader compatible with Next.js `next/image`.
65
+ *
66
+ * Converts a domain + width into a Logos API URL. Does not inject a token
67
+ * or any additional options -- use {@link createQuikturnImageLoader} for that.
68
+ *
69
+ * @example
70
+ * ```tsx
71
+ * import Image from "next/image";
72
+ * import { quikturnImageLoader } from "@quikturn/logos-next";
73
+ *
74
+ * <Image loader={quikturnImageLoader} src="github.com" width={256} height={256} alt="GitHub" />
75
+ * ```
76
+ */
77
+ declare function quikturnImageLoader({ src, width }: ImageLoaderProps): string;
78
+ /**
79
+ * Factory that creates a Quikturn image loader with pre-configured options.
80
+ *
81
+ * The returned function is compatible with Next.js `next/image`'s `loader` prop.
82
+ * Options such as `token`, `format`, `greyscale`, `theme`, and `baseUrl` are
83
+ * captured in the closure so they apply to every call automatically.
84
+ *
85
+ * @example
86
+ * ```tsx
87
+ * import Image from "next/image";
88
+ * import { createQuikturnImageLoader } from "@quikturn/logos-next";
89
+ *
90
+ * const loader = createQuikturnImageLoader({ token: "qt_abc123", format: "webp" });
91
+ *
92
+ * <Image loader={loader} src="github.com" width={256} height={256} alt="GitHub" />
93
+ * ```
94
+ */
95
+ declare function createQuikturnImageLoader(options: QuikturnImageLoaderOptions): (props: ImageLoaderProps) => string;
96
+
97
+ interface QuikturnContextValue {
98
+ token: string;
99
+ baseUrl?: string;
100
+ }
101
+ /** Read the current Quikturn context (token + optional baseUrl). */
102
+ declare function useQuikturnContext(): QuikturnContextValue | null;
103
+ /** Props for the QuikturnProvider component. */
104
+ interface QuikturnProviderProps {
105
+ token: string;
106
+ baseUrl?: string;
107
+ children: React.ReactNode;
108
+ }
109
+ /**
110
+ * Provides a Quikturn token (and optional baseUrl) to all descendant
111
+ * `QuikturnImage` components so they don't need an explicit `token` prop.
112
+ */
113
+ declare function QuikturnProvider({ token, baseUrl, children, }: QuikturnProviderProps): react_jsx_runtime.JSX.Element;
114
+
115
+ export { type ImageLoaderProps, QuikturnImage, type QuikturnImageLoaderOptions, type QuikturnImageProps, QuikturnProvider, createQuikturnImageLoader, quikturnImageLoader, useQuikturnContext };
package/dist/index.mjs ADDED
@@ -0,0 +1,75 @@
1
+ import Image2 from 'next/image';
2
+ import { logoUrl, BASE_URL } from '@quikturn/logos';
3
+ import { createContext, useContext, useMemo, useEffect } from 'react';
4
+ import { jsx } from 'react/jsx-runtime';
5
+ export { QuikturnLogo, QuikturnLogoCarousel, QuikturnLogoGrid, useLogoUrl } from '@quikturn/logos-react';
6
+
7
+ var fired = /* @__PURE__ */ new Set();
8
+ function fireBeacon(token) {
9
+ if (typeof window === "undefined") return;
10
+ if (!token || token.startsWith("sk_")) return;
11
+ if (fired.has(token)) return;
12
+ fired.add(token);
13
+ const img = new Image();
14
+ img.src = `${BASE_URL}/_beacon?token=${token}&page=${encodeURIComponent(location.href)}`;
15
+ }
16
+ var QuikturnContext = createContext(null);
17
+ function useQuikturnContext() {
18
+ return useContext(QuikturnContext);
19
+ }
20
+ function QuikturnProvider({
21
+ token,
22
+ baseUrl,
23
+ children
24
+ }) {
25
+ return /* @__PURE__ */ jsx(QuikturnContext.Provider, { value: { token, baseUrl }, children });
26
+ }
27
+ function QuikturnImage({
28
+ domain,
29
+ token,
30
+ format,
31
+ greyscale,
32
+ theme,
33
+ alt,
34
+ ...imageProps
35
+ }) {
36
+ const ctx = useQuikturnContext();
37
+ const effectiveToken = token ?? ctx?.token ?? "";
38
+ const loader = useMemo(
39
+ () => ({ src, width }) => logoUrl(src, {
40
+ token: effectiveToken || void 0,
41
+ size: width,
42
+ format,
43
+ greyscale,
44
+ theme
45
+ }),
46
+ [effectiveToken, format, greyscale, theme]
47
+ );
48
+ useEffect(() => {
49
+ if (effectiveToken) fireBeacon(effectiveToken);
50
+ }, [effectiveToken]);
51
+ return /* @__PURE__ */ jsx(
52
+ Image2,
53
+ {
54
+ ...imageProps,
55
+ src: domain,
56
+ loader,
57
+ alt: alt ?? `${domain} logo`
58
+ }
59
+ );
60
+ }
61
+ function quikturnImageLoader({ src, width }) {
62
+ return logoUrl(src, { size: width });
63
+ }
64
+ function createQuikturnImageLoader(options) {
65
+ return ({ src, width }) => logoUrl(src, {
66
+ token: options.token,
67
+ size: width,
68
+ format: options.format,
69
+ greyscale: options.greyscale,
70
+ theme: options.theme,
71
+ baseUrl: options.baseUrl
72
+ });
73
+ }
74
+
75
+ export { QuikturnImage, QuikturnProvider, createQuikturnImageLoader, quikturnImageLoader, useQuikturnContext };
@@ -0,0 +1,29 @@
1
+ 'use strict';
2
+
3
+ require('server-only');
4
+ var server = require('@quikturn/logos/server');
5
+
6
+ // src/server.ts
7
+ var cached = null;
8
+ function getServerClient() {
9
+ if (!cached) {
10
+ const key = process.env.QUIKTURN_SECRET_KEY;
11
+ if (!key) {
12
+ throw new Error(
13
+ "QUIKTURN_SECRET_KEY environment variable is not set. Set it in your .env.local file or deployment environment."
14
+ );
15
+ }
16
+ cached = new server.QuikturnLogos({ secretKey: key });
17
+ }
18
+ return cached;
19
+ }
20
+ async function getLogoBuffer(domain, options) {
21
+ return getServerClient().get(domain, options);
22
+ }
23
+
24
+ Object.defineProperty(exports, "QuikturnLogos", {
25
+ enumerable: true,
26
+ get: function () { return server.QuikturnLogos; }
27
+ });
28
+ exports.getLogoBuffer = getLogoBuffer;
29
+ exports.getServerClient = getServerClient;
@@ -0,0 +1,23 @@
1
+ import { ServerGetOptions, QuikturnLogos } from '@quikturn/logos/server';
2
+ export { QuikturnLogos } from '@quikturn/logos/server';
3
+
4
+ /**
5
+ * Returns a singleton {@link QuikturnLogos} server client.
6
+ *
7
+ * Reads the `QUIKTURN_SECRET_KEY` environment variable on first call and
8
+ * caches the client instance for subsequent calls.
9
+ *
10
+ * @throws {Error} If `QUIKTURN_SECRET_KEY` is not set.
11
+ */
12
+ declare function getServerClient(): QuikturnLogos;
13
+ /**
14
+ * Convenience wrapper that fetches a logo buffer for a domain using the
15
+ * cached server client.
16
+ *
17
+ * @param domain - The domain to fetch a logo for (e.g. "github.com").
18
+ * @param options - Optional request options forwarded to `client.get()`.
19
+ * @returns The server logo response containing a Buffer, content type, and metadata.
20
+ */
21
+ declare function getLogoBuffer(domain: string, options?: ServerGetOptions): Promise<ReturnType<QuikturnLogos["get"]>>;
22
+
23
+ export { getLogoBuffer, getServerClient };
@@ -0,0 +1,23 @@
1
+ import { ServerGetOptions, QuikturnLogos } from '@quikturn/logos/server';
2
+ export { QuikturnLogos } from '@quikturn/logos/server';
3
+
4
+ /**
5
+ * Returns a singleton {@link QuikturnLogos} server client.
6
+ *
7
+ * Reads the `QUIKTURN_SECRET_KEY` environment variable on first call and
8
+ * caches the client instance for subsequent calls.
9
+ *
10
+ * @throws {Error} If `QUIKTURN_SECRET_KEY` is not set.
11
+ */
12
+ declare function getServerClient(): QuikturnLogos;
13
+ /**
14
+ * Convenience wrapper that fetches a logo buffer for a domain using the
15
+ * cached server client.
16
+ *
17
+ * @param domain - The domain to fetch a logo for (e.g. "github.com").
18
+ * @param options - Optional request options forwarded to `client.get()`.
19
+ * @returns The server logo response containing a Buffer, content type, and metadata.
20
+ */
21
+ declare function getLogoBuffer(domain: string, options?: ServerGetOptions): Promise<ReturnType<QuikturnLogos["get"]>>;
22
+
23
+ export { getLogoBuffer, getServerClient };
@@ -0,0 +1,23 @@
1
+ import 'server-only';
2
+ import { QuikturnLogos } from '@quikturn/logos/server';
3
+ export { QuikturnLogos } from '@quikturn/logos/server';
4
+
5
+ // src/server.ts
6
+ var cached = null;
7
+ function getServerClient() {
8
+ if (!cached) {
9
+ const key = process.env.QUIKTURN_SECRET_KEY;
10
+ if (!key) {
11
+ throw new Error(
12
+ "QUIKTURN_SECRET_KEY environment variable is not set. Set it in your .env.local file or deployment environment."
13
+ );
14
+ }
15
+ cached = new QuikturnLogos({ secretKey: key });
16
+ }
17
+ return cached;
18
+ }
19
+ async function getLogoBuffer(domain, options) {
20
+ return getServerClient().get(domain, options);
21
+ }
22
+
23
+ export { getLogoBuffer, getServerClient };
package/package.json ADDED
@@ -0,0 +1,90 @@
1
+ {
2
+ "name": "@quikturn/logos-next",
3
+ "version": "1.0.0",
4
+ "description": "Next.js components for the Quikturn Logos API — QuikturnImage with next/image integration, server helpers",
5
+ "license": "MIT",
6
+ "author": "Quikturn",
7
+ "type": "module",
8
+ "sideEffects": false,
9
+ "exports": {
10
+ ".": {
11
+ "types": {
12
+ "import": "./dist/index.d.ts",
13
+ "require": "./dist/index.d.cts"
14
+ },
15
+ "import": "./dist/index.mjs",
16
+ "require": "./dist/index.cjs"
17
+ },
18
+ "./server": {
19
+ "types": {
20
+ "import": "./dist/server.d.ts",
21
+ "require": "./dist/server.d.cts"
22
+ },
23
+ "import": "./dist/server.mjs",
24
+ "require": "./dist/server.cjs"
25
+ }
26
+ },
27
+ "main": "./dist/index.cjs",
28
+ "module": "./dist/index.mjs",
29
+ "types": "./dist/index.d.ts",
30
+ "publishConfig": {
31
+ "access": "public"
32
+ },
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "https://github.com/Quikturn-PowerPoint-Add-In/Logo-SDK.git",
36
+ "directory": "packages/next"
37
+ },
38
+ "bugs": {
39
+ "url": "https://github.com/Quikturn-PowerPoint-Add-In/Logo-SDK/issues"
40
+ },
41
+ "homepage": "https://github.com/Quikturn-PowerPoint-Add-In/Logo-SDK/tree/main/packages/next#readme",
42
+ "keywords": [
43
+ "quikturn",
44
+ "logos",
45
+ "next",
46
+ "company-logos",
47
+ "brand-assets"
48
+ ],
49
+ "engines": {
50
+ "node": ">=20"
51
+ },
52
+ "files": [
53
+ "dist",
54
+ "LICENSE",
55
+ "README.md"
56
+ ],
57
+ "scripts": {
58
+ "build": "tsup",
59
+ "test": "vitest run",
60
+ "test:watch": "vitest",
61
+ "typecheck": "tsc --noEmit",
62
+ "lint": "eslint src/ tests/"
63
+ },
64
+ "dependencies": {
65
+ "@quikturn/logos": "workspace:^",
66
+ "@quikturn/logos-react": "workspace:^",
67
+ "server-only": "^0.0.1"
68
+ },
69
+ "peerDependencies": {
70
+ "next": "^14 || ^15",
71
+ "react": ">=18",
72
+ "react-dom": ">=18"
73
+ },
74
+ "devDependencies": {
75
+ "@semantic-release/changelog": "^6.0.3",
76
+ "@semantic-release/git": "^10.0.1",
77
+ "@testing-library/jest-dom": "^6.6.3",
78
+ "@testing-library/react": "^16.3.0",
79
+ "@types/react": "^19.0.0",
80
+ "@types/react-dom": "^19.0.0",
81
+ "jsdom": "^28.0.0",
82
+ "next": "^15.0.0",
83
+ "react": "^19.0.0",
84
+ "react-dom": "^19.0.0",
85
+ "semantic-release": "^25.0.3",
86
+ "tsup": "^8.5.1",
87
+ "typescript": "^5.9.3",
88
+ "vitest": "^4.0.18"
89
+ }
90
+ }