# How to Fix Next.js Google Fonts Link Tags Not Working: Server-Side Import Guide

> Fix Next.js Google Fonts link tags not working by using static imports in server components. Learn how to correctly implement custom fonts for improved performance.

- Repository: [Vercel/next.js](https://github.com/vercel/next.js)
- Tags: how-to-guide
- Published: 2026-02-16

---

**Google Font link tags fail to generate when you import `next/font/google` inside a client component or omit required configuration options like `subsets`, so you must always use static imports within server components to enable automatic stylesheet injection.**

When implementing nextjs google fonts in modern Next.js applications, missing `<link>` tags or silent font loading failures typically indicate incorrect usage of the server-side font optimization API. The `next/font/google` module introduced in Next.js 13 runs exclusively during server-side rendering to inject preconnect hints and stylesheets, but requires strict implementation patterns to function correctly across the App and Pages routers.

## Why Google Font Link Tags Fail in Next.js

The `next/font/google` loader executes only during SSR to minimize bundle size and optimize loading performance. According to the source code in [`packages/next/font/google/index.js`](https://github.com/vercel/next.js/blob/main/packages/next/font/google/index.js), the API validates the Next.js version at import time and throws a runtime error if invoked in a client-only bundle. When the loader fails, no `<link rel="preload">` or `<link rel="stylesheet">` tags reach the HTML head, leaving you with fallback fonts.

### Client Component Usage

Importing the font in any file marked with `"use client"` forces the loader to run in the browser, where it cannot emit head tags. The code in [`packages/next/font/google/index.js`](https://github.com/vercel/next.js/blob/main/packages/next/font/google/index.js) explicitly guards against this scenario, resulting in the "@next/font/google failed to run" error or silent failures.

### Missing Required Subsets or Weights

The loader validates requests against the Google Fonts API. Omitting the `subsets` array triggers the *Missing specified subset* error documented in `errors/google-fonts-missing-subsets.mdx`, preventing any CSS generation. Similarly, invalid `display` values trigger errors per `errors/google-font-display.mdx` and halt tag injection.

### Dynamic Imports in Client Contexts

Using `import('next/font/google')` or `next/dynamic` with `ssr: false` forces the loader into a client-only execution context. Because the font loader must emit tags during the server render, dynamic imports on the client result in missing fonts and broken styling.

## How next/font/google Works Under the Hood

When you execute a static import, the code resolves to [`packages/font/google/loader.js`](https://github.com/vercel/next.js/blob/main/packages/font/google/loader.js), which re-exports the compiled loader from `packages/font/google/dist/google/loader`. During the build or server render, this loader:

1. Contacts the Google Fonts CSS API
2. Generates a minimal, optimized stylesheet
3. Creates a unique CSS class name (e.g., `inter-var`)
4. Injects the corresponding `<link>` tags into the HTML head via the Next.js server runtime

The generated class name is then exported for use in your components, but the critical stylesheet injection happens only on the server.

## Proper Implementation Methods

### App Router Server Components (app/layout.tsx)

Import the font statically in your root layout without the `"use client"` directive. The loader automatically handles head tag injection.

```tsx
// app/layout.tsx – server component (no "use client")
import './globals.css';
import { Inter } from 'next/font/google';

const inter = Inter({
  subsets: ['latin'],
  weight: ['400', '700'],
  display: 'swap',
});

export default function RootLayout({
  children,
}: React.PropsWithChildren) {
  return (
    <html lang="en">
      <head />
      <body className={inter.className}>{children}</body>
    </html>
  );
}

```

*Source:* [`packages/create-next-app/templates/app/js/app/layout.js`](https://github.com/vercel/next.js/blob/main/packages/create-next-app/templates/app/js/app/layout.js)

### Pages Router (_app.tsx)

In the Pages Router, the default server-rendering context supports `next/font/google` without additional configuration.

```tsx
// pages/_app.tsx – server-rendered (default)
import type { AppProps } from 'next/app';
import { Roboto } from 'next/font/google';

const roboto = Roboto({
  subsets: ['latin'],
  weight: ['400', '500'],
  display: 'optional',
});

export default function MyApp({ Component, pageProps }: AppProps) {
  return (
    <main className={roboto.className}>
      <Component {...pageProps} />
    </main>
  );
}

```

### Antipattern: Client-Only Usage

Never import the font loader in a client component. The following pattern triggers the runtime guard in [`packages/next/font/google/index.js`](https://github.com/vercel/next.js/blob/main/packages/next/font/google/index.js) and prevents link tag generation:

```tsx
// ❌ This file has "use client" at the top
'use client';
import { Inter } from 'next/font/google'; // ❌ will throw at runtime

```

If you need font styles inside a client component, compute the class name in a parent server component and pass it as a prop.

## Manual Fallback for Edge Cases

When you cannot use `next/font/google`—such as in external packages or legacy setups—manually inject the Google Fonts CDN links using the `Head` component from `next/head`.

```tsx
// pages/_document.tsx or a custom <Head> component
import Head from 'next/head';

export default function CustomHead() {
  return (
    <Head>
      <link
        rel="preconnect"
        href="https://fonts.gstatic.com"
        crossOrigin="anonymous"
      />
      <link
        href="https://fonts.googleapis.com/css2?family=Krona+One&display=swap"
        rel="stylesheet"
      />
    </Head>
  );
}

```

Supported `display` values are `swap`, `fallback`, `optional`, and `block`, as enforced by the validation logic in `errors/google-font-display.mdx`.

## Summary

- **next/font/google** is a server-only API that runs during SSR to inject `<link>` tags automatically.
- Always provide required `subsets` (e.g., `['latin']`) and valid `display` values to prevent loader errors.
- Import fonts statically in server components ([`app/layout.tsx`](https://github.com/vercel/next.js/blob/main/app/layout.tsx) or [`pages/_app.tsx`](https://github.com/vercel/next.js/blob/main/pages/_app.tsx)), never in files marked with `"use client"`.
- Dynamic imports of the font loader force client-side execution and break stylesheet injection.
- For unsupported scenarios, manually add Google Fonts CDN links using `next/head` with proper `preconnect` hints.

## Frequently Asked Questions

### Can I use next/font/google in a client component?

No. The API is explicitly designed for server-side execution only. According to [`packages/next/font/google/index.js`](https://github.com/vercel/next.js/blob/main/packages/next/font/google/index.js), importing it in a client component triggers a runtime error because the loader cannot emit `<link>` tags from the browser. Pass the generated `className` from a server parent component instead.

### Why am I getting a "Missing specified subset" error?

The Google Fonts loader requires at least one subset (such as `'latin'`) to construct the API request. The error originates from `errors/google-fonts-missing-subsets.mdx` and prevents tag generation until you add the `subsets` array to your font configuration object.

### Can I dynamically import Google Fonts using next/dynamic?

No. Dynamic imports with `ssr: false` or runtime `import()` statements force the loader to execute in the browser, where it lacks access to the HTML head. This results in missing fonts and potentially the "@next/font/google failed to run" error. Use static imports at the top of server components only.

### What Next.js version is required for next/font/google?

You need Next.js 13.0.0 or higher. The runtime guard in [`packages/next/font/google/index.js`](https://github.com/vercel/next.js/blob/main/packages/next/font/google/index.js) checks the installed version and throws if it detects versions below 13.0.0. For older versions, use the legacy `@next/font` package or manual CDN links.