How to handle FOUC with server render mode

When you create a server-side blazor app through Radzen Studio you end up with a _Host.cshtml that looks more or less like this:

<component type="typeof(RadzenTheme)" render-mode="ServerPrerendered" param-Theme="@("software-dark")" />

<link rel="icon" href="favicon.ico" />
<link href="css/site.css" rel="stylesheet" />

<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />

Notice that the render mode is 'ServerPrerendered'. With this setting (or with just 'Server') I am experiencing FOUC flash, the App.razor loads in, but for a split second I see content without styling. This happens only on the first login to app or after refreshing a page. Navigation over server-side pages when a hub has already been established does not cause a FOUC.

How to address this?

I see people in this thread trying to address this issue, but either I can't get it to work right, or it should be handled differently with server-side rendering: css - Eliminate flash of unstyled content - Stack Overflow

Spent half the night, got this workaround to do the thing:

In _Host.cshtml I added the following lines before rendering any components:

<link href="/_content/Radzen.Blazor/css/software-dark-base.css?v=5.3.5.0" rel="stylesheet" />
<link rel="preload" href="/_content/Radzen.Blazor/fonts/SourceSans3VF-Upright.ttf.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="https://secure.gravatar.com/avatar/d41d8cd98f00b204e9800998ecf8427e?d=retro&s=36" as="image">
<link rel="preload" href="/images/nuclear-logo.png" as="image">
<link rel="preload" href="/_content/Radzen.Blazor/fonts/MaterialSymbolsOutlined.woff2" as="font" type="font/woff2" crossorigin="anonymous">

I traced that all these resources are fetched after the call to framework/blazor.server.js (or websocket initialization?) is made and the timely absence of these causes FOUC, so I force to load them before any components do.

But this really does not feel right in general, am I really supposed to list all these resources manually?

Hi @Nick_Farsi,

render-mode="ServerPrerendered" means that the component is rendered from the server so RadzenTheme outputs <link href="/_content/Radzen.Blazor/css/software-dark-base.css?v=5.3.5.0" rel="stylesheet" />. Our local tests show this is what happens with a new .NET 7 Blazor Server application. You can test it yourself by running a command line utility that fetches web pages such as curl for example curl https://localhost:5001. You would see something like this:

<base href="/" />
<!--Blazor:{"sequence":0,"type":"server","prerenderId":"150a93fb9f864dcba196033a71790d95","descriptor":"CfDJ8JaEucHKl0xBhD337sXJCZ4MBYGaFCxZYeMBSHmDPAe8FnG4PmGJJ1nKLUCkYZhtQC9wNzpSnAycyduqyr9GNBBmU9UBqBYaDMUZ\u002B6n2jy\u002BBmLQvj44pHG1IMgt3aburlqEgny6j1NS/m7L1dpqaD5Aoew2uZLnvSoPW7Z7PJllWIduzfEWNkoYo6RuSCEJlqxMKYg64tBmY1yztEN2HCTvzLEI4I6dw\u002B4/uZjjjUQbzo8y/a\u002BY53dBAua4pV5i3fY3llZM7gAZ1y8ZgTfRqGlSecSqsp5fuEaBNpUqROen5yndc9JDDMTHjs2fijfpfHw93G8PXEgecMSrdyWs2Urb7TSZevkTPIG\u002BtjtFA5VqOp5amk6u8cGqdNinOAn4v85rHl5LuhFYpBtGA2gXR78WsPeG7FUGMTnsOYPoL1hfCrhYxrP/0qkMTJZLAVVol22AQ8VXhQb4qe7JD0G4ucEwRop5GeSIh/gzmY3x9IxHE"}-->
<link rel="stylesheet" href="_content/Radzen.Blazor/css/software-dark-base.css?v=5.3.5.0" />
<!--Blazor:{"prerenderId":"150a93fb9f864dcba196033a71790d95"}-->

Maybe the Blazor runtime does something with this link tag the first time it loads (for example rendering it again) which could lead to the flicker that you see.

You have to options:

  1. Create a .NET 8 application as .NET 7 is out of support already and the end of support of .NET 6 approaches (November 12, 2024). .NET 8 apps use a different rendering mode
  2. Continue including <link href="/_content/Radzen.Blazor/css/software-dark-base.css?v=5.3.5.0" rel="stylesheet" />. This is what the recommended approach was before the release of Radzen.Blazor 5.0 and RadzenTheme.

Hi @korchev,

But my application is .NET 8.0 (yes, I created it from 7.0 studio template, but later I updated in to .NET 8.0)

<TargetFramework>net8.0</TargetFramework>

I also have Radzen.Blazor Version="5.3.5"

And I see that scaffolded Host.cshtml uses (or supposed to) the ThemeService:

@inject Radzen.ThemeService ThemeService

@{
    var theme = HttpContext.Request.Cookies["BlazingServerTheme"];

    if (!string.IsNullOrEmpty(theme))
    {
        ThemeService.SetTheme(theme, true);
    }
}

However all this does not prevent FOUC - the resources are loaded before a hub is connected unless I load them manually.

The .net 8 template is quite different. You are still using the older code.

My answer remains the same:

  1. Create a .NET 8 application (not .NET 7 which is then manually changed to .net 8) or
  2. Use <link href="/_content/Radzen.Blazor/css/software-dark-base.css"> to include the theme.

There is no other solution that we know of.