Quick Start

Build your first Trident-powered blog page in 5 minutes.

This guide assumes you have a Next.js 14+ project with the App Router. For other frameworks, see the examples.

Step 1: Create the client

Create a shared client instance in your lib folder:

// lib/trident.ts
import { createTridentClient } from "@trident/client";

export const trident = createTridentClient({
  apiKey: process.env.TRIDENT_API_KEY!,
});

Step 2: Create the blog listing page

Create a page that lists all your articles:

// app/blog/page.tsx
import { trident } from "@/lib/trident";
import Link from "next/link";

export default async function BlogPage() {
  const { data: articles, pagination } = await trident.getArticles({
    product: "my-product",
    limit: 20,
  });

  return (
    <div className="mx-auto max-w-4xl py-12">
      <h1 className="text-3xl font-bold">Blog</h1>
      <div className="mt-8 space-y-6">
        {articles.map((article) => (
          <article key={article.id} className="border-b pb-6">
            <Link href={`/blog/${article.slug}`}>
              <h2 className="text-xl font-semibold hover:text-blue-600">
                {article.title}
              </h2>
            </Link>
            <p className="mt-2 text-gray-600">{article.excerpt}</p>
            <time className="mt-2 text-sm text-gray-500">
              {new Date(article.publishedAt!).toLocaleDateString()}
            </time>
          </article>
        ))}
      </div>
    </div>
  );
}

// Enable ISR with 1 hour revalidation
export const revalidate = 3600;

Step 3: Create the article page

Create a dynamic page that renders article content:

// app/blog/[slug]/page.tsx
import { trident } from "@/lib/trident";
import { ArticleRenderer } from "@trident/client/components";
import { generateArticleMetadata } from "@trident/client/nextjs";
import { notFound } from "next/navigation";

interface Props {
  params: { slug: string };
}

export async function generateMetadata({ params }: Props) {
  try {
    const article = await trident.getArticle(params.slug);
    return generateArticleMetadata(article, {
      baseUrl: "https://yourdomain.com",
    });
  } catch {
    return { title: "Article Not Found" };
  }
}

export default async function ArticlePage({ params }: Props) {
  try {
    const article = await trident.getArticle(params.slug);

    return (
      <article className="mx-auto max-w-3xl py-12">
        <h1 className="text-4xl font-bold">{article.title}</h1>
        {article.content && (
          <ArticleRenderer article={article} className="mt-8" />
        )}
      </article>
    );
  } catch {
    notFound();
  }
}

// Generate static paths at build time
export async function generateStaticParams() {
  const entries = await trident.getSitemap();
  return entries.map((entry) => ({ slug: entry.slug }));
}

export const revalidate = 3600;

Step 4: Add the sitemap

Generate a sitemap.xml automatically:

// app/sitemap.ts
import { trident } from "@/lib/trident";
import { generateSitemapEntries } from "@trident/client/nextjs";

export default async function sitemap() {
  const entries = await trident.getSitemap();

  return generateSitemapEntries(entries, {
    baseUrl: "https://yourdomain.com",
    urlPattern: "/blog/:slug",
  });
}

export const revalidate = 3600;

Step 5: Style the components

All components render with data-trident-* attributes for easy CSS targeting:

/* styles/trident.css */
[data-trident-paragraph] {
  @apply text-gray-700 leading-relaxed mb-4;
}

[data-trident-heading="2"] {
  @apply text-2xl font-bold mt-8 mb-4;
}

[data-trident-heading="3"] {
  @apply text-xl font-semibold mt-6 mb-3;
}

[data-trident-list] {
  @apply my-4 pl-6;
}

[data-trident-list="ordered"] {
  @apply list-decimal;
}

[data-trident-list="unordered"] {
  @apply list-disc;
}

[data-trident-callout] {
  @apply my-4 p-4 rounded-lg border-l-4;
}

[data-trident-callout="tip"] {
  @apply bg-green-50 border-green-500;
}

[data-trident-callout="warning"] {
  @apply bg-yellow-50 border-yellow-500;
}

[data-trident-table] {
  @apply w-full my-4 border-collapse;
}

[data-trident-th],
[data-trident-td] {
  @apply border border-gray-300 px-4 py-2;
}