Repository: next.js
Issue: Next.js 15 stable codemod has now caused my local font imports to produce hydration errors
Labels: bug,Font (next/font)

I've updated the repo, simplified it, and created easy steps to reproduce this issue based off @timneutkens feedback. I'm editing the original comment here below to reflect all that.

### Link to the code that reproduces this issue

https://github.com/tr1s/trisanity-test

### To Reproduce

1. `git clone https://github.com/tr1s/trisanity-test.git`
1. `cd trisanity-test`
1. `npm i`
1. `npm run dev`

The hydration errors:

![CleanShot 2024-10-23 at 14 32 29@2x](https://github.com/user-attachments/assets/571924d5-5c4c-4d78-a0b0-651b6fac062a)

### Current vs. Expected behavior

Current behaviour: a working app with hydration errors
Expected behaviour: a working app without hydration errors

### Provide environment information

```bash
Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 24.0.0: Tue Sep 24 23:39:07 PDT 2024; root:xnu-11215.1.12~1/RELEASE_ARM64_T6000
  Available memory (MB): 65536
  Available CPU cores: 10
Binaries:
  Node: 20.17.0
  npm: 10.9.0
  Yarn: N/A
  pnpm: N/A
Relevant Packages:
  next: 15.0.1 // Latest available version is detected (15.0.1).
  eslint-config-next: 15.0.1
  react: 19.0.0-rc-69d4b800-20241021
  react-dom: 19.0.0-rc-69d4b800-20241021
  typescript: 5.6.3
Next.js Config:
  output: N/A
```

### Which area(s) are affected? (Select all that apply)

Font (next/font)

### Which stage(s) are affected? (Select all that apply)

next dev (local)

### Additional context

I ran the Next.js 15 codemod and now I have hydration errors on my local font imports. I've tried with and without turbopack, same issues.

There are two ways to remove the hydration error:
1. Remove the default `src/app/layout.tsx`
1. Go to the `src/app/(frontend)/layout.tsx` file and remove the `className` block from the `<html> tag:

```
return (
	<html
		lang="en"
		className={`
        		${GTFAdieu.variable}
        		${GTFAdieu_Slanted.variable}
        		${GTFAdieu_Backslant.variable}
        		${Source_Sans_3.variable}
      		`}
	>
		<body>
			<Nav />
			<main role="main" id="main-content" tabIndex={-1}>
				{children}
			</main>
		</body>
	</html>
);
```

The `src/app/layout.tsx` was left as is so it wouldn't mess up any Sanity Studio UI. Then I created a `src/app/(frontend)/layout.tsx` where the layout for my frontend would live—this is where I imported my fonts. I was following along with [this Sanity tutorial](https://www.sanity.io/learn/course/content-driven-web-application-foundations) in which they did this.

For this setup when using a default layout and a nested (frontend) layout I was not getting any hydration errors until Next.js RC2 and beyond. RC1 was working fine, and that's what this tutorial was based off.

Here's my `fonts.js` that was working previously with Next 15 RC1:

```
import localFont from 'next/font/local';

export const GTFAdieu = localFont({
	variable: '--font-GTFAdieu',
	src: [
		{
			path: '../../public/fonts/GTFAdieuTRIAL-Light.otf',
			weight: '300',
			style: 'normal',
		},
		{
			path: '../../public/fonts/GTFAdieuTRIAL-Regular.otf',
			weight: '400',
			style: 'normal',
		},
		{
			path: '../../public/fonts/GTFAdieuTRIAL-Bold.otf',
			weight: '700',
			style: 'normal',
		},
	],
});

export const GTFAdieu_Backslant = localFont({
	variable: '--font-GTFAdieu-Backslant',
	src: [
		{
			path: '../../public/fonts/GTFAdieuTRIAL-LightBackslant.otf',
			weight: '300',
			style: 'italic',
		},
		{
			path: '../../public/fonts/GTFAdieuTRIAL-RegularBackslant.otf',
			weight: '400',
			style: 'italic',
		},
		{
			path: '../../public/fonts/GTFAdieuTRIAL-BoldBackslant.otf',
			weight: '700',
			style: 'italic',
		},
	],
});

export const GTFAdieu_Slanted = localFont({
	variable: '--font-GTFAdieu-Slanted',
	src: [
		{
			path: '../../public/fonts/GTFAdieuTRIAL-RegularSlanted.otf',
			weight: '400',
			style: 'italic',
		},
		{
			path: '../../public/fonts/GTFAdieuTRIAL-BoldSlanted.otf',
			weight: '700',
			style: 'italic',
		},
	],
});

export const Source_Sans_3 = localFont({
	variable: '--font-Source-Sans-3',
	src: [
		{
			path: '../../public/fonts/source-sans-3-v4-latin-regular.woff2',
			weight: '400',
			style: 'normal',
		},
		{
			path: '../../public/fonts/source-sans-3-v4-latin-700.woff2',
			weight: '700',
			style: 'normal',
		},
	],
});
```

That's about all the context I can provide. Given that, do we know what may be going on here?