Next.js
Merid, App Router'da hiçbir ayar gerektirmeden çalışır. Bu site de Merid ile yapılmış bir Next.js 16 uygulaması.
npx create-next-app@latest my-app
cd my-app
npx @meridui/cli initinit, @meridui/react'i kurar, stil dosyasını app/layout.tsx'te import eder ve şablonun globals.css dosyasını düzeltir (aşağıda). Her değişikliği yazmadan önce diff olarak gösterir.
Kurulum
// app/layout.tsx
import type { Metadata, Viewport } from "next";
import "@meridui/react/styles.css";
import "./globals.css"; // kendi CSS'in Merid'inkinden sonra (Tailwind'de tersi, aşağıya bak)
export const metadata: Metadata = {
title: { default: "Acme", template: "%s — Acme" },
};
export const viewport: Viewport = {
// Açık ve koyu temada --mrd-bg ile eşleşir; mobil tarayıcı arayüzü sayfayla bütünleşir.
themeColor: [
{ media: "(prefers-color-scheme: light)", color: "#ffffff" },
{ media: "(prefers-color-scheme: dark)", color: "#0b0d12" },
],
};
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="tr">
<body>{children}</body>
</html>
);
}Base layer tipografi, arka plan ve focus stillerini dokümana sıfır specificity ile uygular; hiçbir sınıf gerekmez. transpilePackages girdisi de gerekmez. Server component dosyalarında düz parça adlarını (DialogRoot, TabsList, …) ve router linkleri için asChild'ı kullan; ayrıntılar Server component'ler sayfasında.
Şablonun globals.css dosyası
create-next-app'in yazdığı app/globals.css dosyasındaki kurallar bir cascade layer'da olmadığı için Merid'inkileri ezer.
Tailwind'li şablonda (varsayılan) iki şeyi değiştirmen gerekir. body kuralı Arial'ı ve şablonun renklerini koyar; onu sil. Tailwind'in reset'i Preflight ise base adlı bir layer'dadır: Merid'in stil dosyası önce yüklenirse bu layer Merid'in üstüne çıkar ve butonlarla input'ların padding'ini, kenarlığını ve arka planını siler. Layer sırasını globals.css'in en üstüne yaz ve globals.css'i Merid'den önce import et:
/* app/globals.css */
@layer theme, base, merid, components, utilities;
@import "tailwindcss";// app/layout.tsx
import "./globals.css";
import "@meridui/react/styles.css";Tailwind'siz şablonda üç kural sorun çıkarır: her component'in iç boşluğunu sıfırlayan * { padding: 0; margin: 0 }, Link'i görünmez yapan a { color: inherit; text-decoration: none } ve body'deki Arial. Bunları sil, body { margin: 0 }'ı bırak. --background ve --foreground değişkenleri kalabilir; Merid onları kullanmaz.
npx @meridui/cli init bu değişiklikleri yapar ve yazmadan önce sorar. Yalnızca şablondaki haliyle duran kuralları kaldırır, senin düzenlemelerin kalır. Bu kurallardan biri kaldıkça npx @meridui/cli doctor uyarır. Merid'in token'larını Tailwind temana taşımak için Tailwind CSS sayfasına bak.
Server component'ler
Her etkileşimli component kendi "use client" direktifiyle gelir; bu yüzden bir server component'te @meridui/react'ten import edip doğrudan render'layabilirsin. Görsel component'ler (Card, Stack, Heading, Text, Badge, Table, …) kendilerine ait hiçbir istemci JavaScript'i olmadan sunucuda render'lanır. Event handler'lar yine de bir client sınırı ister; bkz. Server component'ler.
// app/projects/page.tsx — bir server component
import { Badge, Card, Heading, Stack, Text } from "@meridui/react";
export default async function Projects() {
const projects = await db.project.findMany();
return (
<Stack gap={4}>
<Heading level={1} size="h2">Projeler</Heading>
{projects.map((p) => (
<Card key={p.id} variant="outline">
<Text tone="ink" weight="medium">{p.name}</Text>
<Badge tone={p.live ? "success" : "neutral"}>{p.live ? "Yayında" : "Taslak"}</Badge>
</Card>
))}
</Stack>
);
}Linkler
Anchor render'layan component'ler bir as prop'u alır; next/link verdiğinde istemci tarafı gezinme ve prefetch kazanırlar:
import NextLink from "next/link";
import { Breadcrumb, Card, SidebarNav } from "@meridui/react";
<SidebarNav.Item as={NextLink} href="/settings" active={pathname === "/settings"}>Ayarlar</SidebarNav.Item>
<Breadcrumb.Link as={NextLink} href="/projects">Projeler</Breadcrumb.Link>
<Card as={NextLink} href={`/projects/${id}`} interactive>…</Card>Overlay tetikleyicileri (Dialog.Trigger, Popover.Trigger, DropdownMenu.Trigger, Tooltip) asChild alır; yani bir next/link aynı zamanda bir tooltip'in ya da menünün tetikleyicisi olabilir.
Button, Link ve Breadcrumb.Link asChild alır. Bu, as={NextLink} geçilemeyen server component dosyalarında da çalışır:
<Button asChild variant="primary">
<NextLink href="/new">Yeni proje</NextLink>
</Button>
<Link asChild>
<NextLink href="/pricing">Fiyatlandırma</NextLink>
</Link>getHref verilen Pagination düz anchor'lar render'lar (sayfa baştan yüklenir). Bunları next/link üzerinden yönlendirmek için renderLink ver: renderLink={({ page, ...props }) => <NextLink {...props} />}. Uygulama içinde onPageChange ve router.push da kullanabilirsin; getHref'i herkese açık sayfalarda taranabilir sayfalama için sakla.
Fontlar
Merid, Geist ve Geist Mono'yu paketinde taşır ve stil dosyasındaki @font-face ile yükler; başka bir şey gerekmez. Bunun yerine next/font kullanmak için (kendi sunucunda barınan, önceden yüklenen, layout kayması olmayan) token'ları onun değişkenine yönlendir:
import { Inter } from "next/font/google";
const inter = Inter({ subsets: ["latin"], variable: "--font-inter" });
<html lang="tr" className={inter.variable}>/* globals.css */
:root {
--mrd-font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;
}Tarayıcılar yalnızca kullanılan font dosyalarını indirir; token başka bir yeri gösterdiği anda paketteki Geist dosyaları hiç istenmez.
Yanıp sönmeden dark mode
İlk boyamadan önce <head> içindeki inline bir script ile data-theme'i ayarla ve attribute sunucu render'ından farklı olacağı için <html>'e suppressHydrationWarning ekle. Bkz. Dark mode stratejileri.