Customization

Last updated on 2026-03-26

The Social Media Dashboard Kit is designed to be customized for your social media management product. All components use design tokens and Tailwind CSS utilities, making brand adaptation straightforward.

Changing Colors

Update CSS custom properties in app/globals.css. The default teal/cyan theme uses oklch hue 175. Change the hue to rebrand the entire kit:

:root {
  /* Change from teal (hue 175) to indigo (hue 270) */
  --primary: oklch(0.45 0.2 270);
  --primary-foreground: oklch(0.98 0 0);
  --accent: oklch(0.94 0.02 270);
  --accent-foreground: oklch(0.35 0.15 270);
  --ring: oklch(0.55 0.18 270);
}

.dark {
  --primary: oklch(0.7 0.18 270);
  --primary-foreground: oklch(0.15 0.02 270);
}

All 35+ screens automatically inherit the new colors -- buttons, badges, links, charts, sidebar accents, calendar highlights, and focus rings all update at once. Platform brand colors (Instagram pink, Twitter blue, etc.) remain fixed.

Changing Typography

Configure fonts in app/layout.tsx:

import { Inter, DM_Sans, JetBrains_Mono } from "next/font/google";

const inter = Inter({ subsets: ["latin"], variable: "--font-inter" });
const dmSans = DM_Sans({ subsets: ["latin"], variable: "--font-dm-sans" });
const jetbrainsMono = JetBrains_Mono({ subsets: ["latin"], variable: "--font-jetbrains" });

Swap these for any Google Font or local font files. The CSS variables --font-sans, --font-heading, and --font-mono control body text, headings, and code respectively.

Replacing Seed Data

All mock data lives in data/seed.ts. Replace it with your data source:

Social Media API calls

import { getSocialPosts } from "@/lib/api"

export default async function ContentPage() {
  const posts = await getSocialPosts()
  return <PostGrid posts={posts} />
}

Database (Prisma, Drizzle)

import { db } from "@/lib/db"

const posts = await db.post.findMany({
  orderBy: { scheduledAt: "desc" },
  include: { metrics: true, platforms: true },
})

Social Media APIs

// Instagram Graph API
const res = await fetch(
  `https://graph.instagram.com/me/media?fields=id,caption,media_type,timestamp,like_count,comments_count&access_token=${token}`
)
const { data: posts } = await res.json()

Extending Components

Use the cn() utility (from lib/utils.ts) to add custom classes without conflicts:

import { Button } from "@/components/ui/button"

<Button className="rounded-full shadow-lg" size="lg">
  Schedule Post
</Button>

Adding Component Variants

Components use class-variance-authority for variant management:

const badgeVariants = cva("...", {
  variants: {
    variant: {
      default: "...",
      published: "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200",
      scheduled: "bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200",
      draft: "bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-200",
    },
  },
})

Customizing the Sidebar

Edit components/layout/app-sidebar.tsx to add or remove navigation items:

const navItems = [
  { label: "Dashboard", href: "/", icon: LayoutDashboard },
  { label: "Content", href: "/content", icon: FileText },
  { label: "Compose", href: "/compose", icon: PenSquare },
  { label: "Calendar", href: "/calendar", icon: Calendar },
  { label: "Analytics", href: "/analytics", icon: BarChart3 },
  { label: "Reports", href: "/reports", icon: FileBarChart },
  { label: "Inbox", href: "/inbox", icon: Inbox },
  { label: "Media", href: "/media", icon: Image },
  // Remove items you don't need
  // Add items for new pages
]

Each item takes a label, href, and a Lucide icon component. Active state highlighting is handled automatically based on the current pathname.

Customizing the Header

Edit components/layout/app-header.tsx to modify quick actions in the top bar:

  • Command palette trigger -- the search input that opens Cmd+K
  • Notification bell -- links to the notifications settings
  • Theme toggle -- switches between light and dark mode
  • User menu -- dropdown with profile, settings, and sign out

Remove or reorder these actions to fit your workflow.

Adding New Platforms

The kit supports 6 platforms out of the box. To add a new platform:

  1. Add the platform to the SocialPlatform type in types/index.ts:
export type SocialPlatform =
  | "instagram"
  | "twitter"
  | "facebook"
  | "linkedin"
  | "tiktok"
  | "youtube"
  | "pinterest"  // new platform
  1. Add the platform icon and color in components/social/platform-icon.tsx:
const platformConfig = {
  // ...existing platforms...
  pinterest: {
    icon: <PinterestIcon />,
    color: "#E60023",
    label: "Pinterest",
  },
}
  1. Add the platform to components/social/platform-badge.tsx with the matching color.

  2. Update data/seed.ts to include mock data for the new platform.

  3. The platform dashboard (/platforms/pinterest) will automatically work via the [platform] dynamic route.

Adding New Dashboard Pages

  1. Create a new route in app/(dashboard)/your-page/page.tsx
  2. The page automatically inherits the dashboard layout (sidebar, header)
  3. Add a sidebar link in components/layout/app-sidebar.tsx
// app/(dashboard)/mentions/page.tsx
export default function MentionsPage() {
  return (
    <div className="space-y-6">
      <h1 className="font-heading text-2xl font-bold">Brand Mentions</h1>
      {/* Your content */}
    </div>
  )
}

Integrating Social Media APIs

Buffer API

// app/api/buffer/posts/route.ts
export async function POST(request: Request) {
  const { text, media, platforms, scheduledAt } = await request.json()
  const res = await fetch("https://api.bufferapp.com/1/updates/create.json", {
    method: "POST",
    headers: { Authorization: `Bearer ${process.env.BUFFER_ACCESS_TOKEN}` },
    body: new URLSearchParams({
      text,
      profile_ids: platforms.join(","),
      scheduled_at: scheduledAt,
    }),
  })
  return Response.json(await res.json())
}

Hootsuite API

// app/api/hootsuite/schedule/route.ts
export async function POST(request: Request) {
  const { text, mediaUrls, socialProfileIds, scheduledSendTime } = await request.json()
  const res = await fetch("https://platform.hootsuite.com/v1/messages", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.HOOTSUITE_TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      text,
      mediaUrls,
      socialProfileIds,
      scheduledSendTime,
    }),
  })
  return Response.json(await res.json())
}

Twitter/X API v2

// app/api/twitter/tweet/route.ts
export async function POST(request: Request) {
  const { text } = await request.json()
  const res = await fetch("https://api.twitter.com/2/tweets", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.TWITTER_BEARER_TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ text }),
  })
  return Response.json(await res.json())
}

Meta (Instagram/Facebook) Graph API

// app/api/meta/publish/route.ts
export async function POST(request: Request) {
  const { pageId, message, imageUrl } = await request.json()
  const res = await fetch(
    `https://graph.facebook.com/v19.0/${pageId}/feed`,
    {
      method: "POST",
      body: new URLSearchParams({
        message,
        link: imageUrl,
        access_token: process.env.META_PAGE_ACCESS_TOKEN!,
      }),
    }
  )
  return Response.json(await res.json())
}

Integrating Analytics Platforms

Sprout Social

import { createClient } from "@/lib/sprout-social"

const analytics = await createClient.getAnalytics({
  profileIds: ["instagram_123", "twitter_456"],
  metrics: ["impressions", "engagements", "follower_growth"],
  dateRange: { start: "2026-03-01", end: "2026-03-31" },
})

Supabase

import { createClient } from "@supabase/supabase-js"

const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)

const { data: posts } = await supabase
  .from("posts")
  .select("*, metrics:post_metrics(*), platforms:post_platforms(*)")
  .order("scheduled_at", { ascending: false })

Removing Unused Features

Delete directories you don't need:

  • Don't need inbox? Delete app/(dashboard)/inbox/ and components/social/conversation-item.tsx, message-bubble.tsx
  • Don't need reports? Delete app/(dashboard)/reports/ and components/reports/
  • Don't need competitor tracking? Delete app/(dashboard)/analytics/competitors/ and components/analytics/competitor-card.tsx
  • Don't need media library? Delete app/(dashboard)/media/ and components/content/media-uploader.tsx
  • Don't need onboarding? Delete app/onboarding/
  • Run pnpm build to verify no broken imports

Using shadcn/ui CLI

Add new components alongside the kit:

npx shadcn@latest add <component-name>

Components install to components/ui/ and integrate seamlessly with the existing design tokens. The kit uses the new-york style with CSS variables enabled.