Using a Headless Browser in .Net to Render HTML with Javascript

I am looking to render an HTML page that includes basic Javascript using a headless browser in a .Net C# application on the server side. Ultimately, I aim to retrieve the fully rendered HTML source code after processing.

I believe there are several free or open-source libraries that could assist with this task, such as:

  • Awesomium
  • GeckoFX
  • CefSharp
  • Berkelium

To illustrate my needs, here’s an example of the HTML code prior to rendering:

<!DOCTYPE html>
<html>
<head>
    <title>Sample</title>
    <meta charset="utf-8" />
    <script type="text/javascript">
        function DisplayCurrency(amount) {
            document.write(amount.toLocaleString('en-US', { style: 'decimal', minimumFractionDigits: 2, maximumFractionDigits: 2 }));
        }
    </script>
</head>
<body>
    <h1>Sample</h1>
    <table>
        <tr>
            <td>Cost:</td>
            <td><script>DisplayCurrency(275)</script></td>
        </tr>
    </table>
</body>
</html>

The expected output HTML after rendering would look like this:

<!DOCTYPE html>
<html>
<head>
    <title>Sample</title>
    <meta charset="utf-8" />
    <script type="text/javascript">
        function DisplayCurrency(amount) {
            document.write(amount.toLocaleString('en-US', { style: 'decimal', minimumFractionDigits: 2, maximumFractionDigits: 2 }));
        }
    </script>
</head>
<body>
    <h1>Sample</h1>
    <table>
        <tr>
            <td>Cost</td>
            <td>275.00</td>
        </tr>
    </table>
</body>
</html>

Here, the Javascript invocation <td><script>DisplayCurrency(275)</script></td> results in <td>275.00</td> after rendering.

Could someone assist me in achieving this functionality by providing a sample code? You can use any free .Net browser control library in the example.

Please note that I can pass either the HTML code or a URL to the rendering method, and since this implementation is server-side, I believe using a headless browser is essential.

Hi Grace,

To achieve the rendering of an HTML page containing JavaScript in a .Net C# application, using a headless browser like CefSharp is a practical choice. CefSharp is popular due to its efficiency and open-source nature.

Here's a basic implementation example using CefSharp:

using CefSharp;
using CefSharp.OffScreen;
using System;
using System.Threading.Tasks;

namespace RenderHtmlExample {
    class Program {
        static async Task Main() {
            // Initialize CefSharp
            var settings = new CefSettings();
            Cef.Initialize(settings);

            // Create the browser instance
            var browser = new ChromiumWebBrowser();

            // HTML to render
            var html = @"


    Sample
    
    


    

Sample

Cost
";
        // Load the HTML
        await browser.GetMainFrame().LoadHtmlStringAsync(html);

        // Wait for rendering to complete
        await browser.WaitForInitialLoadAsync();

        // Retrieve the rendered HTML
        var renderedHtml = await browser.GetMainFrame().GetSourceAsync();

        // Output the result
        Console.WriteLine(renderedHtml);

        // Cleanup
        Cef.Shutdown();
    }
}

}

This script initializes a headless Chromium browser, loads the HTML, processes the JavaScript, and retrieves the fully rendered HTML source.

Ensure you have CefSharp dependencies set in your project. This implementation will render the JavaScript on the server side as needed.

Let me know if you need further clarification!

Hey Grace,

I agree with the suggestions of using a headless browser to render your HTML with JavaScript in a .Net C# app. CefSharp and Playwright Sharp are both great options. Here's a simple example using CefSharp:

using CefSharp;
using CefSharp.OffScreen;
using System;
using System.Threading.Tasks;

namespace RenderHtmlExample {
    class Program {
        static async Task Main() {
            var settings = new CefSettings();
            Cef.Initialize(settings);

            var browser = new ChromiumWebBrowser();

            var html = @"


    Sample
    
    


    

Sample

Cost
";
        await browser.GetMainFrame().LoadHtmlStringAsync(html);
        await browser.WaitForInitialLoadAsync();

        var renderedHtml = await browser.GetMainFrame().GetSourceAsync();
        Console.WriteLine(renderedHtml);

        Cef.Shutdown();
    }
}

}

Follow this script to initialize CefSharp, load your HTML, process the JavaScript, and extract the rendered source. Make sure you have CefSharp dependencies in your project.

Grace, if you're considering alternatives or wish to see a different approach, using Playwright Sharp as a headless browser for rendering HTML and processing JavaScript is another compelling option. Playwright is known for its support across various browsers and efficiently executes JavaScript.

Below is an example implementation with Playwright Sharp in C#:

using Microsoft.Playwright;
using System;
using System.Threading.Tasks;

namespace RenderHtmlExample {
    class Program {
        public static async Task Main() {
            // Initialize Playwright
            var playwright = await Playwright.CreateAsync();
            var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions { Headless = true });
            var page = await browser.NewPageAsync();

            // HTML to render
            var html = @"


    Sample
    
    


    

Sample

Cost
";
        // Navigate to the given HTML
        await page.SetContentAsync(html);

        // Wait for all scripts to complete
        await page.WaitForLoadStateAsync(LoadState.NetworkIdle);

        // Retrieve the rendered HTML
        var renderedHtml = await page.ContentAsync();

        // Output the result
        Console.WriteLine(renderedHtml);

        // Cleanup
        await browser.CloseAsync();
    }
}

}

In this example, we use Playwright's capabilities to load and render HTML content, run JavaScript, and finally fetch the rendered output. Ensure Playwright Sharp is properly installed in your project by adding it through NuGet.

This method can be a strong alternative to CefSharp and is particularly helpful when cross-browser testing or specific browser functionality is desired on the server side.