*This section applies to Blazor Server and hosted Blazor WebAssembly apps that prerender Razor components. Prerendering is covered in .* While an app is prerendering, certain actions, such as calling into JavaScript (JS), aren't possible. For the following example, the `setElementText1` function is placed inside the `` element. The function is called with and doesn't return a value. [!INCLUDE[](~/blazor/includes/js-location.md)] ```html ``` > [!WARNING] > **The preceding example modifies the Document Object Model (DOM) directly for demonstration purposes only.** Directly modifying the DOM with JS isn't recommended in most scenarios because JS can interfere with Blazor's change tracking. For more information, see . The [`OnAfterRender{Async}` lifecycle event](xref:blazor/components/lifecycle#after-component-render-onafterrenderasync) isn't called during the prerendering process on the server. Override the `OnAfterRender{Async}` method to delay JS interop calls until after the component is rendered and interactive on the client after prerendering. `Pages/PrerenderedInterop1.razor`: :::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/Pages/prerendering/PrerenderedInterop1.razor" highlight="2-3,10-17"::: > [!NOTE] > The preceding example pollutes the client with global methods. For a better approach in production apps, see [JavaScript isolation in JavaScript modules](xref:blazor/js-interop/call-javascript-from-dotnet#javascript-isolation-in-javascript-modules). > > Example: > > ```javascript > export setElementText1 = (element, text) => element.innerText = text; > ``` The following component demonstrates how to use JS interop as part of a component's initialization logic in a way that's compatible with prerendering. The component shows that it's possible to trigger a rendering update from inside . The developer must be careful to avoid creating an infinite loop in this scenario. For the following example, the `setElementText2` function is placed inside the `` element. The function is called with and returns a value. [!INCLUDE[](~/blazor/includes/js-location.md)] ```html ``` > [!WARNING] > **The preceding example modifies the Document Object Model (DOM) directly for demonstration purposes only.** Directly modifying the DOM with JS isn't recommended in most scenarios because JS can interfere with Blazor's change tracking. For more information, see . Where is called, the is only used in and not in any earlier lifecycle method because there's no JS element until after the component is rendered. [`StateHasChanged`](xref:blazor/components/lifecycle#state-changes-statehaschanged) is called to rerender the component with the new state obtained from the JS interop call (for more information, see ). The code doesn't create an infinite loop because `StateHasChanged` is only called when `data` is `null`. `Pages/PrerenderedInterop2.razor`: :::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/Pages/prerendering/PrerenderedInterop2.razor" highlight="3-4,18,23-29"::: > [!NOTE] > The preceding example pollutes the client with global methods. For a better approach in production apps, see [JavaScript isolation in JavaScript modules](xref:blazor/js-interop/call-javascript-from-dotnet#javascript-isolation-in-javascript-modules). > > Example: > > ```javascript > export setElementText2 = (element, text) => { > element.innerText = text; > return text; > }; > ```