Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges
  • Chrome Extension
  • Skill Manager

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Maple Nextjs Style

ASecurity

Next.js / Vercel OpenTelemetry style for Maple: instrumentation.ts, @vercel/otel bootstrap, native @opentelemetry/api call sites, inline endpoint + ingest key, no raw NodeSDK replacement, @maple-dev/browser on the client.

1,799 stars
0 votes
0 copies
0 views
Added 10/1/2026
developmentjavascripttypescriptjavanextjsnodegitapi

Works with

cliapi

Security Analysis

A100/100

Scanned 10/1/2026

$npx -y skills add MapleTechLabs/maple --skill maple-nextjs-style --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Maple Nextjs Style?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Maple Nextjs Style
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/mapletechlabs-maple-nextjs-style/badge)](https://www.skillsdirectory.com/skills/mapletechlabs-maple-nextjs-style)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
Files
SKILL.md
---
name: maple-nextjs-style
description: "Next.js / Vercel OpenTelemetry style for Maple: instrumentation.ts, @vercel/otel bootstrap, native @opentelemetry/api call sites, inline endpoint + ingest key, no raw NodeSDK replacement, @maple-dev/browser on the client."
---

# Maple Next.js style

For Next.js apps, use the framework entrypoint, `instrumentation.ts` with `@vercel/otel`.

```ts
// instrumentation.ts
import { registerOTel } from "@vercel/otel"

const MAPLE_ENDPOINT = "https://ingest.maple.dev" // EU: https://ingest.eu.maple.dev
const MAPLE_KEY = "MAPLE_TEST" // public ingest key (maple_pk_…), or MAPLE_TEST until the user has one

export function register() {
	registerOTel({
		serviceName: "my-next-app",
		attributes: {
			"deployment.environment.name": process.env.VERCEL_ENV ?? "development",
			"vcs.repository.url.full": "https://github.com/acme/my-next-app",
			"vcs.ref.head.revision": process.env.VERCEL_GIT_COMMIT_SHA,
		},
		traceExporter: {
			url: `${MAPLE_ENDPOINT}/v1/traces`,
			headers: { authorization: `Bearer ${MAPLE_KEY}` },
		},
	})
}
```

Do not replace this with a custom `NodeSDK` bootstrap unless the repo is not a standard Next/Vercel app or already has a custom provider to extend.

For JavaScript/TypeScript LLM providers, use provider instrumentation instead of manual child spans. For Anthropic, add OpenInference in the same bootstrap and keep call sites native. This example uses `@vercel/otel@2.x`. If the installed types are v1, use `logRecordProcessor` (singular). Current `@opentelemetry/sdk-logs` takes `new BatchLogRecordProcessor({ exporter })`; older releases took the exporter as the first argument, and the wrong form silently drops every log. Check the installed `.d.ts`.

```ts
import Anthropic from "@anthropic-ai/sdk"
import { AnthropicInstrumentation } from "@arizeai/openinference-instrumentation-anthropic"
import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http"
import { BatchLogRecordProcessor } from "@opentelemetry/sdk-logs"
import { registerOTel } from "@vercel/otel"

const MAPLE_ENDPOINT = "https://ingest.maple.dev"
const MAPLE_KEY = "MAPLE_TEST"

const anthropicInstrumentation = new AnthropicInstrumentation({
	traceConfig: {
		hideInputs: true,
		hideOutputs: true,
	},
})

anthropicInstrumentation.manuallyInstrument(Anthropic)

export function register() {
	registerOTel({
		serviceName: "my-next-app",
		instrumentations: [anthropicInstrumentation],
		traceExporter: {
			url: `${MAPLE_ENDPOINT}/v1/traces`,
			headers: { authorization: `Bearer ${MAPLE_KEY}` },
		},
		logRecordProcessors: [
			new BatchLogRecordProcessor({
				exporter: new OTLPLogExporter({
					url: `${MAPLE_ENDPOINT}/v1/logs`,
					headers: { authorization: `Bearer ${MAPLE_KEY}` },
				}),
			}),
		],
	})
}
```

## Route handlers

Use native OTel APIs where auto-instrumentation is blind.

```ts
import { metrics, SpanStatusCode, trace } from "@opentelemetry/api"

const tracer = trace.getTracer("my-next-app")
const meter = metrics.getMeter("my-next-app")
const generated = meter.createCounter("replies.generated")

export async function POST(request: Request) {
	const tenantId = request.headers.get("x-tenant-id") ?? "unknown"
	return tracer.startActiveSpan("reply.generate", async (span) => {
		try {
			span.setAttribute("tenant.id", tenantId)
			generated.add(1, { "tenant.id": tenantId, outcome: "success" })
			return Response.json({ ok: true })
		} catch (err) {
			span.recordException(err as Error)
			span.setStatus({ code: SpanStatusCode.ERROR, message: (err as Error).message })
			throw err
		} finally {
			span.end()
		}
	})
}
```

For TypeScript route handlers, wrap the business operation in `tracer.startActiveSpan(...)` with `try` / `catch` / `finally` (the shape in `maple-onboarding-style`). `@vercel/otel` already gives every request a span, so span the operation that matters rather than every handler by reflex. Don't hide the pattern behind a local helper.

If a route has an LLM call and OpenInference / provider instrumentation supports that SDK, do not wrap the provider call. Leave `client.messages.create(...)` / equivalent in place and put business context on the active product span or structured log. Do not duplicate provider/model/token attributes in route-level spans, logs, or metrics when OpenInference already reports them. Maple does not price tokens; see `maple-onboarding-style` "LLM calls" for cost and conversation grouping. For Anthropic in Next.js/ESM, keep the instrumentation instance and `manuallyInstrument(Anthropic)` call at module scope so it runs once and before route code.

Match the `@vercel/otel` logs option to the installed version: `@vercel/otel@1.x` takes `logRecordProcessor` (singular), `@vercel/otel@2.x` takes `logRecordProcessors` (plural). For normal Next.js / Vercel apps, do not guard `registerOTel(...)` behind `NEXT_RUNTIME`; Next calls `instrumentation.ts` in the appropriate runtime and `@vercel/otel` handles its own runtime differences.

`console.info` is not OTLP log export. If there is no existing logger bridge, use `@opentelemetry/api-logs` for production log records. Remove pre-existing `console.*` calls that duplicate the same structured OTel log event:

```ts
import { logs, SeverityNumber } from "@opentelemetry/api-logs"

const logger = logs.getLogger("my-next-app")

logger.emit({
	severityNumber: SeverityNumber.INFO,
	severityText: "INFO",
	body: "generated reply",
	attributes: {
		"tenant.id": tenantId,
		"gen_ai.provider.name": "anthropic",
		"gen_ai.request.model": model,
		"app.gen_ai.use_case": "support.reply",
		outcome: "success",
	},
})
```

## Client side

The browser half of the app uses `@maple-dev/browser` from a client component rendered in the root layout. `init()` is a no-op during server rendering, so module scope is safe.

```tsx
// app/maple.tsx
"use client"

import { MapleBrowser } from "@maple-dev/browser"

MapleBrowser.init({
	ingestKey: "MAPLE_TEST", // public key (maple_pk_…) only, never maple_sk_
	serviceName: "my-next-app-web",
	region: "us", // "eu" for EU organizations
	environment: process.env.NODE_ENV,
	serviceVersion: process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA,
})

export function Maple() {
	return null
}
```

Render `<Maple />` inside `<body>` in `app/layout.tsx` (Pages Router: import `./maple` from `pages/_app.tsx`). Give it a different `serviceName` from the server so browser and server spans stay distinguishable. Same-origin `fetch` calls to route handlers carry `traceparent`, so browser and server spans join one trace.

## Configuration and smoke

Inline the endpoint and ingest key in `instrumentation.ts` and pass them explicitly to `registerOTel`. Do not rely on `OTEL_EXPORTER_OTLP_*` env vars. The Maple ingest key is project-scoped and write-only, and inline config avoids Vercel's env-propagation quirks in preview builds.

Smoke-check with tools already in the repo (`npm run typecheck`, `npm run build`), plus a real app request where practical. Do not invent fragile inline Node scripts that import TypeScript source files directly, and do not assume `ts-node` exists unless it is already installed.

Attribution

MapleTechLabsMapleTechLabs
View sourceSee grades on GitHubMore from MapleTechLabs →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Clean Code

Pragmatic coding standards - concise, direct, no over-engineering, no unnecessary comments

304955 votes

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

286712 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2222 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Writing Plans

Use when you have a spec or requirements for a multi-step task, before touching code

2927051 votes
View all in development →