> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/kapishdima/fonttrio/llms.txt
> Use this file to discover all available pages before exploring further.

# Mixing Multiple Pairings

> Learn how to install multiple font pairings, switch between them, and create custom combinations in your shadcn/ui project.

Fonttrio allows you to install multiple pairings in the same project, making it easy to switch between different font combinations or use different pairings for different sections of your application.

## Why Mix Pairings?

Installing multiple pairings is useful for:

* **A/B testing** different typography styles before committing
* **Multi-section apps** where different areas need different moods (e.g., marketing landing page + documentation + app dashboard)
* **Theme switching** to let users choose their preferred reading experience
* **Custom combinations** by mixing fonts from different pairings

## Installing Multiple Pairings

You can install as many pairings as you want. Each pairing adds its fonts to the `registry/` directory:

<Steps>
  <Step title="Install First Pairing">
    Start with your primary pairing.

    ```bash theme={null}
    npx shadcn@latest add https://www.fonttrio.xyz/r/editorial.json
    ```

    This installs:

    * `registry/fonts/playfair-display.tsx`
    * `registry/fonts/source-serif-4.tsx`
    * `registry/fonts/jetbrains-mono.tsx`
    * `registry/pairings/editorial.tsx`
  </Step>

  <Step title="Install Second Pairing">
    Add another pairing for comparison or mixing.

    ```bash theme={null}
    npx shadcn@latest add https://www.fonttrio.xyz/r/minimal.json
    ```

    This adds:

    * `registry/fonts/inter.tsx` (new)
    * `registry/fonts/jetbrains-mono.tsx` (skipped, already exists)
    * `registry/pairings/minimal.tsx` (new)
  </Step>

  <Step title="Install Additional Pairings">
    Keep adding pairings as needed.

    ```bash theme={null}
    npx shadcn@latest add https://www.fonttrio.xyz/r/corporate.json
    npx shadcn@latest add https://www.fonttrio.xyz/r/impact.json
    ```
  </Step>
</Steps>

<Note>
  Shared fonts (like JetBrains Mono, which appears in many pairings) are only installed once. Subsequent pairings will reuse the existing font file.
</Note>

## Switching Between Pairings

Once you have multiple pairings installed, you can switch between them in your layout:

### Method 1: Direct Import Swap

The simplest way is to change which pairing you import:

```tsx app/layout.tsx theme={null}
// Switch this import to change the active pairing
import { editorial } from "@/registry/pairings/editorial";
// import { minimal } from "@/registry/pairings/minimal";
// import { corporate } from "@/registry/pairings/corporate";

import "./globals.css";

export default function RootLayout({ children }) {
  return (
    <html 
      className={`
        ${editorial.heading.variable} 
        ${editorial.body.variable} 
        ${editorial.mono.variable}
      `}
    >
      <body>{children}</body>
    </html>
  );
}
```

To switch pairings:

1. Comment out the current import
2. Uncomment the desired pairing import
3. Update the className to use the new pairing's variables

### Method 2: Environment-Based Selection

Use environment variables to select pairings:

```tsx app/layout.tsx theme={null}
import { editorial } from "@/registry/pairings/editorial";
import { minimal } from "@/registry/pairings/minimal";
import { corporate } from "@/registry/pairings/corporate";
import "./globals.css";

const pairings = {
  editorial,
  minimal,
  corporate,
};

const activePairing = pairings[
  (process.env.NEXT_PUBLIC_FONT_PAIRING as keyof typeof pairings) || "editorial"
];

export default function RootLayout({ children }) {
  return (
    <html 
      className={`
        ${activePairing.heading.variable} 
        ${activePairing.body.variable} 
        ${activePairing.mono.variable}
      `}
    >
      <body>{children}</body>
    </html>
  );
}
```

Set in `.env.local`:

```bash .env.local theme={null}
NEXT_PUBLIC_FONT_PAIRING=minimal
```

### Method 3: User-Selectable Themes

Allow users to switch fonts dynamically:

```tsx app/providers.tsx theme={null}
"use client";

import { createContext, useContext, useState, ReactNode } from "react";
import { editorial } from "@/registry/pairings/editorial";
import { minimal } from "@/registry/pairings/minimal";
import { corporate } from "@/registry/pairings/corporate";

type PairingName = "editorial" | "minimal" | "corporate";

const pairings = { editorial, minimal, corporate };

const FontContext = createContext<{
  pairing: PairingName;
  setPairing: (name: PairingName) => void;
}>({
  pairing: "editorial",
  setPairing: () => {},
});

export function FontProvider({ children }: { children: ReactNode }) {
  const [pairing, setPairing] = useState<PairingName>("editorial");
  const activePairing = pairings[pairing];

  return (
    <FontContext.Provider value={{ pairing, setPairing }}>
      <div 
        className={`
          ${activePairing.heading.variable} 
          ${activePairing.body.variable} 
          ${activePairing.mono.variable}
        `}
      >
        {children}
      </div>
    </FontContext.Provider>
  );
}

export const useFontPairing = () => useContext(FontContext);
```

Use in layout:

```tsx app/layout.tsx theme={null}
import { FontProvider } from "./providers";
import "./globals.css";

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <FontProvider>
          {children}
        </FontProvider>
      </body>
    </html>
  );
}
```

Create a font switcher component:

```tsx components/font-switcher.tsx theme={null}
"use client";

import { useFontPairing } from "@/app/providers";

export function FontSwitcher() {
  const { pairing, setPairing } = useFontPairing();

  return (
    <div className="flex gap-2">
      <button
        onClick={() => setPairing("editorial")}
        className={pairing === "editorial" ? "font-bold" : ""}
      >
        Editorial
      </button>
      <button
        onClick={() => setPairing("minimal")}
        className={pairing === "minimal" ? "font-bold" : ""}
      >
        Minimal
      </button>
      <button
        onClick={() => setPairing("corporate")}
        className={pairing === "corporate" ? "font-bold" : ""}
      >
        Corporate
      </button>
    </div>
  );
}
```

<Warning>
  User-selectable fonts can cause a flash of unstyled content (FOUC) during hydration. Consider storing the preference in localStorage and applying it before the initial render.
</Warning>

## Using Different Pairings in Different Sections

You can apply different pairings to different parts of your app:

### Method 1: Section-Specific Classes

Import all pairings and apply their variables to specific sections:

```tsx app/layout.tsx theme={null}
import { editorial } from "@/registry/pairings/editorial";
import { minimal } from "@/registry/pairings/minimal";
import { impact } from "@/registry/pairings/impact";
import "./globals.css";

export default function RootLayout({ children }) {
  return (
    <html 
      className={`
        ${editorial.heading.variable} 
        ${editorial.body.variable} 
        ${editorial.mono.variable}
        ${minimal.heading.variable}
        ${minimal.body.variable}
        ${impact.heading.variable}
        ${impact.body.variable}
      `}
    >
      <body>{children}</body>
    </html>
  );
}
```

Create section-specific CSS:

```css app/globals.css theme={null}
/* Default to Editorial for blog content */
@layer base {
  :root {
    --font-heading: var(--font-playfair-display);
    --font-body: var(--font-source-serif-4);
    --font-mono: var(--font-jetbrains-mono);
  }
}

/* Use Minimal for dashboard */
.dashboard {
  --font-heading: var(--font-inter);
  --font-body: var(--font-inter);
}

/* Use Impact for landing page */
.landing {
  --font-heading: var(--font-bebas-neue);
  --font-body: var(--font-barlow);
}
```

Apply to sections:

```tsx theme={null}
<div className="dashboard">
  <h1>Dashboard</h1>  {/* Uses Inter */}
  <p>Analytics data</p>
</div>

<div className="landing">
  <h1>Welcome</h1>  {/* Uses Bebas Neue */}
  <p>Get started</p>
</div>
```

### Method 2: Route-Based Pairings

Apply different pairings to different route groups:

```tsx app/(blog)/layout.tsx theme={null}
import { editorial } from "@/registry/pairings/editorial";

export default function BlogLayout({ children }) {
  return (
    <div className={`
      ${editorial.heading.variable} 
      ${editorial.body.variable} 
      ${editorial.mono.variable}
    `}>
      {children}
    </div>
  );
}
```

```tsx app/(dashboard)/layout.tsx theme={null}
import { minimal } from "@/registry/pairings/minimal";

export default function DashboardLayout({ children }) {
  return (
    <div className={`
      ${minimal.heading.variable} 
      ${minimal.body.variable} 
      ${minimal.mono.variable}
    `}>
      {children}
    </div>
  );
}
```

## Creating Custom Combinations

Mix and match individual fonts from different pairings:

<Steps>
  <Step title="Install Source Pairings">
    Install pairings that contain the fonts you want.

    ```bash theme={null}
    npx shadcn@latest add https://www.fonttrio.xyz/r/editorial.json
    npx shadcn@latest add https://www.fonttrio.xyz/r/minimal.json
    npx shadcn@latest add https://www.fonttrio.xyz/r/impact.json
    ```
  </Step>

  <Step title="Import Individual Fonts">
    Import only the fonts you need.

    ```tsx app/layout.tsx theme={null}
    // Heading from Impact pairing
    import { bebasNeue } from "@/registry/fonts/bebas-neue";
    // Body from Minimal pairing
    import { inter } from "@/registry/fonts/inter";
    // Mono from Editorial pairing
    import { jetbrainsMono } from "@/registry/fonts/jetbrains-mono";
    ```
  </Step>

  <Step title="Apply Custom Combination">
    Create your own pairing object.

    ```tsx app/layout.tsx theme={null}
    const customPairing = {
      heading: bebasNeue,
      body: inter,
      mono: jetbrainsMono,
    };

    export default function RootLayout({ children }) {
      return (
        <html className={`
          ${customPairing.heading.variable} 
          ${customPairing.body.variable} 
          ${customPairing.mono.variable}
        `}>
          <body>{children}</body>
        </html>
      );
    }
    ```
  </Step>

  <Step title="Override CSS Variables">
    Point the variables to your chosen fonts.

    ```css app/globals.css theme={null}
    @layer base {
      :root {
        --font-heading: var(--font-bebas-neue);
        --font-body: var(--font-inter);
        --font-mono: var(--font-jetbrains-mono);
      }
    }
    ```
  </Step>
</Steps>

<Note>
  When mixing fonts, ensure they work well together. Consider contrast (serif vs sans), weight compatibility, and x-height. Test thoroughly with real content.
</Note>

## Common Use Cases

### Marketing Site + Documentation

Use a bold pairing for the landing page and a readable pairing for docs:

```tsx theme={null}
// Landing page uses Impact pairing
<div className="landing">
  <h1>Bold Marketing Message</h1>
</div>

// Docs use Editorial pairing
<div className="docs">
  <h1>Documentation Title</h1>
  <p>Detailed technical content...</p>
</div>
```

### Multi-Brand Application

Different brands within the same app:

```tsx theme={null}
const brandPairings = {
  brandA: editorial,
  brandB: minimal,
  brandC: corporate,
};

function BrandSection({ brand, children }) {
  const pairing = brandPairings[brand];
  
  return (
    <div className={`
      ${pairing.heading.variable}
      ${pairing.body.variable}
      ${pairing.mono.variable}
    `}>
      {children}
    </div>
  );
}
```

### A/B Testing Fonts

Randomly assign pairings for testing:

```tsx theme={null}
const pairings = [editorial, minimal, corporate];
const randomPairing = pairings[Math.floor(Math.random() * pairings.length)];

// Or use a proper A/B testing framework
const pairing = useABTest('font-test', {
  control: editorial,
  variant: minimal,
});
```

### Seasonal Themes

Switch pairings based on time of year:

```tsx theme={null}
function getSeasonalPairing() {
  const month = new Date().getMonth();
  
  if (month >= 10 || month <= 1) return cozyWinterPairing;
  if (month >= 2 && month <= 4) return freshSpringPairing;
  if (month >= 5 && month <= 7) return brightSummerPairing;
  return warmAutumnPairing;
}

const pairing = getSeasonalPairing();
```

## Managing Multiple Pairings

### Keep Track of Installed Pairings

Maintain a list of your active pairings:

```ts lib/pairings.ts theme={null}
import { editorial } from "@/registry/pairings/editorial";
import { minimal } from "@/registry/pairings/minimal";
import { corporate } from "@/registry/pairings/corporate";
import { impact } from "@/registry/pairings/impact";

export const PAIRINGS = {
  editorial,
  minimal,
  corporate,
  impact,
} as const;

export type PairingName = keyof typeof PAIRINGS;

export function getPairing(name: PairingName) {
  return PAIRINGS[name];
}
```

### Load Fonts on Demand

For performance, only load fonts when needed:

```tsx theme={null}
import dynamic from "next/dynamic";

const EditorialFonts = dynamic(() => 
  import("@/registry/pairings/editorial").then(m => m.editorial)
);

const MinimalFonts = dynamic(() => 
  import("@/registry/pairings/minimal").then(m => m.minimal)
);
```

<Warning>
  Dynamic font loading can cause layout shifts. This approach is only recommended for user-selectable fonts, not for initial page load.
</Warning>

### Update Typography Scale per Pairing

Each pairing may need different CSS adjustments:

```css app/globals.css theme={null}
/* Editorial: Generous spacing for reading */
.editorial h1 { font-size: 2.5rem; line-height: 1.2; }
.editorial p { line-height: 1.75; }

/* Minimal: Compact and efficient */
.minimal h1 { font-size: 2rem; line-height: 1.25; }
.minimal p { line-height: 1.6; }

/* Impact: Large and bold */
.impact h1 { font-size: 4rem; line-height: 1; }
.impact p { line-height: 1.5; }
```

## Best Practices

<Steps>
  <Step title="Limit the Number of Pairings">
    Don't install too many pairings. 2-4 is usually enough. Each pairing adds to your bundle size.
  </Step>

  <Step title="Maintain Consistency">
    If using multiple pairings, ensure they're used consistently across similar contexts. Don't randomly switch fonts.
  </Step>

  <Step title="Test Performance">
    Monitor page load times when adding multiple pairings. Each font adds HTTP requests and increases bundle size.
  </Step>

  <Step title="Document Your Choices">
    Comment your code to explain why you're using specific pairings in specific contexts.
  </Step>

  <Step title="Consider Users">
    If allowing users to switch fonts, persist their choice in localStorage and respect their preference across sessions.
  </Step>
</Steps>

## Performance Considerations

### Font Loading Impact

Each pairing typically includes 3 fonts. If you install 3 pairings, you could have up to 9 fonts (though duplicates are shared).

```tsx theme={null}
// Editorial: 3 fonts
// Minimal: 2 new fonts (shares mono)
// Corporate: 2 new fonts (shares mono)
// Total: 7 unique fonts loaded
```

### Optimize Font Loading

Use `next/font` optimizations:

```tsx theme={null}
import { Inter } from "next/font/google";

const inter = Inter({
  subsets: ["latin"],
  display: "swap",        // Prevent invisible text
  preload: true,          // Preload critical fonts
  fallback: ["system-ui"], // Fallback fonts
});
```

### Subset Fonts

Only load required character sets:

```tsx theme={null}
const font = Font({
  subsets: ["latin"],  // Not latin-ext, cyrillic, etc.
  weight: ["400", "700"],  // Only weights you use
});
```

## Troubleshooting

### Fonts Not Switching

If changing pairings doesn't update fonts:

1. Verify font variables are applied to the correct element (usually `<html>`)
2. Check that CSS variables in `globals.css` point to the right fonts
3. Clear browser cache and reload
4. Restart your dev server

### CSS Variables Conflicting

If multiple pairings conflict:

1. Use scoped classes instead of global `:root` variables
2. Ensure each section has unique class names
3. Check specificity in DevTools to see which styles are winning

### Performance Issues

If page load is slow with multiple pairings:

1. Reduce the number of installed pairings
2. Only load fonts needed for the current page
3. Use font subsetting to reduce file sizes
4. Consider using a variable font instead of multiple weights

## Next Steps

<CardGroup cols={2}>
  <Card title="Customize Typography" icon="sliders" href="/guides/customizing-typography">
    Adjust typography scales for each pairing.
  </Card>

  <Card title="Use with shadcn/ui" icon="puzzle-piece" href="/guides/using-with-shadcn">
    Apply mixed pairings to shadcn/ui components.
  </Card>
</CardGroup>
