Implementing a nextjs 13 app with the app directory and the Client and Server Component.
When displaying the source HTML, my body is empty and only contains scripts and JSON.
<!DOCTYPE html>
<html id="__next_error__">
<head>
<script src="/_next/static/chunks/polyfills.js" nomodule=""></script>
</head>
<body>
<script src="/_next/static/chunks/webpack.js" async=""></script>
<script src="/_next/static/chunks/main-app.js" async=""></script>
</body>
</html>
The JSON/script part is after this html and contains the whole page. As you can see, my body is empty, which I would like to avoid for SEO reasons.
When trying with the former manner with a page, I have the html displaying correctly in the body in an html tag.
Did I miss something that prevents SSR in nextjs 13?
In my Layout, I have a Client Component that wraps the whole App like that :
<AppWrapper appCurrentLang="{appCurrentLang}"> {children} </AppWrapper>;
I don't think it causes the SSR to fail, because even if I add a <p> tag on the root layout, it still doesn't display in the body tag in the source.
Here is the first part of the content displayed after the html :
<script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"M1:{\"id\":\"./node_modules/next/dist/client/components/app-router.js\",\"name\":\"\",\"chunks\":[\"app-client-internals:app-client-internals\"],\"async\":false}\nM2:{\"id\":\"./app/providers.jsx\",\"name\":\"Providers\",\"chunks\":[\"app/layout:app/layout\"],\"async\":false}\nM3:{\"id\":\"./node_modules/next/dist/client/components/layout-router.js\",\"name\":\"\",\"chunks\":[\"app-client-internals:app-client-internals\"],\"async\":false}\nM4:{\"id\":\"./node_modules/next/dist/client/components/render-from-template-context.js\",\"name\":\"\",\"chunks\":[\"app-cl"])</script><script>self.__next_f.push([1,"ient-internals:app-client-internals\"],\"async\":false}\n"])</script><script>self.__next_f.push([1,"J0:[\"$\",\"#1\",null,{\"assetPrefix\":\"\",\"initialCanonicalUrl\":\"/posts/teslas-biggest-threat\",\"initialTree\":[\"\",{\"children\":[\"posts\",{\"children\":[[\"postURL\",\"teslas-biggest-threat\",\"oc\"],{\"children\":[\"\",{}]}]}]},null,null,true],\"initialHead\":[\"$\",\"title\",null,{\"children\":\"My TEST Next.js App\"}],\"children\":[[],[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/app/layout.css?ts=1676839989010\",\"precedence\":\"high\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"data-test\":\"test\",\"children\":[\"$\",\"body\",null,{\"children\":[[\"$\",\"p\",null,{\"children\":\"okkk\"}],[\"$\",\"#2\",null,{\"langHeaders\":\"fr-FR\",\"children\":[\"$\",\"#3\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"hasLoading\":false,\"template\":[\"$\",\"#4\",null,{}],\"notFound\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"-apple-system, BlinkMacSystemFont, Roboto, \\\"Segoe UI\\\", \\\"Fira Sans\\\", Avenir, \\\"Helvetica Neue\\\", \\\"Lucida Grande\\\", sans-serif\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}]}],[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"\\n body { margin: 0; color: #000
Would anyone have an idea ?
The current Next.js Font Optimization docs and the #next/font API Reference describe how to bring in Google Fonts as well as local font files, but the best practice for bringing in Typekit / Adobe Fonts is not described.
What is the best way to use Typekit / Adobe Fonts so that Next.js optimizations are applied?
#next/font has no support for Typekit yet and there isn't any related issue open on their GitHub repo (probably due to legal restrictions imposed by Typekit itself).
However, this doesn't mean that you cannot use Typekit fonts with Next.js. Prior to Next.js 13, it had a feature called automatic font optimization which still exists, and supports Typekit (added in vercel/next.js#24834).
It will basically inline your font CSS. So, if you have:
// pages/_document.tsx
import { Html, Head, Main, NextScript } from 'next/document'
const Document = () => {
return (
<Html>
<Head>
<link rel="stylesheet" href="https://use.typekit.net/plm1izr.css" />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
export default Document
Then Next.js will generate your documents having some content like this in head (saves a request to Typekit):
<link rel="preconnect" href="https://use.typekit.net" crossorigin />
<!-- ... -->
<style data-href="https://use.typekit.net/plm1izr.css">
#import url('https://p.typekit.net/p.css?s=1&k=plm1izr&ht=tk&f=32266&a=23152309&app=typekit&e=css');
#font-face {
font-family: 'birra-2';
src: url('https://use.typekit.net/af/23e0ad/00000000000000003b9b410c/27/l?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n7&v=3')
format('woff2'),
url('https://use.typekit.net/af/23e0ad/00000000000000003b9b410c/27/d?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n7&v=3')
format('woff'),
url('https://use.typekit.net/af/23e0ad/00000000000000003b9b410c/27/a?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n7&v=3')
format('opentype');
font-display: auto;
font-style: normal;
font-weight: 700;
font-stretch: normal;
}
.tk-birra-2 {
font-family: 'birra-2', serif;
}
</style>
Here is the integration suite, you can check it out for different ways to add that stylesheet link: https://github.com/vercel/next.js/tree/canary/test/integration/font-optimization/fixtures/with-typekit (some of those methods are deprecated and will give you warnings).
I'm trying to load the Ubuntu-Bold font-family to my web application (ASP.NET CORE API + Angular). The Ubuntu-Bold.ttf file is located on assets/fonts folder and I also added #font-face { font-family: 'Ubuntu-Bold'; src: url(assets/fonts/Ubuntu-Bold.ttf); } body { margin: 0; font-family: 'Ubuntu-Bold'; } in to the styles.scss file. The font-family its applied to my application but after 2 seconds after the application started running.
Default font-family appears first at the beginning of application:
After 2 second the desired font-family its applied:
As you can see there its a big difference between this two fonts so I'm trying to find a solution in order to apply my font Ubuntu-Bold before the application its displayed in order to not see that change of family fonts after 2 seconds after application started.
you can use preload on your link tag, it tells the browser to load this stylesheet before the main part of your web app.
it should look something like that:
<link rel="preload" href="your/path/xxx.woff" as="font" type="font/woff" crossorigin>
or if you want your entire styles to load first
<link rel="preload" href="style.css" as="style">
you can read about it here
I want my global CSS file to load asynchronous, i.e without render-blocking. My page is waiting for FCP until it gets CSS loaded.
So, How can I achieve this in next js.
What I am getting :
<link rel="stylesheet" href="/_next/static/css/eb4e3a560474a24ae771.css" data-n-g="">
What is Expected :
<link rel="stylesheet" href="/_next/static/css/eb4e3a560474a24ae771.css" data-n-g="" media="all" onload="this.media='all'">
NextJS documentation on Font Optimization https://nextjs.org/docs/basic-features/font-optimization says that they transform provided <link> to preconnect with added style:
// Before
<link
href="https://fonts.googleapis.com/css2?family=Inter&display=optional"
rel="stylesheet"
/>
// After
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<style data-href="https://fonts.googleapis.com/css2?family=Inter&display=optional">
#font-face{font-family:'Inter';font-style:normal...
</style>
Now, you just need to adapt GET parameter display=[value] to adapt to font-display standard https://developer.mozilla.org/en-US/docs/Web/CSS/#font-face/font-display. The list is:
/* Keyword values */
font-display: auto;
font-display: block;
font-display: swap;
font-display: fallback;
font-display: optional;
Many are for mostly non-blocking (small block) display. All of them are explained in the Mozilla link, but the one I prefer, font-display: swap that gives extremely small block for font to load and if not in time, infinite swap period to change the font everywhere when it's loaded:
swap
Gives the font face an extremely small block period and an
infinite swap period.
Font block period
If the font face is not loaded, any element
attempting to use it must render an invisible fallback font face. If
the font face successfully loads during this period, it is used
normally.
Font swap period
If the font face is not loaded, any element
attempting to use it must render a fallback font face. If the font
face successfully loads during this period, it is used normally.
This way we can chose what fits better for us. If it still blocks a lot, I guess you'll have to put the link at the bottom of page.
I'm using a CMS and therefore can only amend the CSS file. I have the following code in that file:
<style>
#import url('https://fonts.googleapis.com/css2?family=Montserrat&display=swap');
.h1_section_hero {
Font-family: 'Montserrat';
}
</style>
However it's not changing in the browser. I'm assuming that I don't have to download the font as i'm importing it within the file? thanks
It looks like your google font link is invalid, you are missing a ? between css2 and the family key:
'https://fonts.googleapis.com/css2?family=Montserrat&display=swap'
If you were to open both urls into your browser you will see that your original url is broken, and that the correct one above shows the fonts.
Create a separate link to the stylesheet rather than trying to import. The markup below is taken from the Google Fonts API doc and works just fine in my browser:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Crimson+Pro">
<style>
body {
font-family: 'Crimson Pro', serif;
font-size: 48px;
}
</style>
</head>
<body>
<div>Making the Web Beautiful!</div>
</body>
</html>