In this tutorial, you’ll learn how to create a web app for scanning documents using Blazor, Microsoft’s framework for building client-side UIs with C# and HTML. To integrate the scanning functionalities, you’ll use the Scanbot Web Document Scanner SDK.

You’ll achieve this in three steps:
- Preparing the project
- Implementing the document scanning functionalities
- Building the UI
Prerequisites
- VS Code – however, you can also follow along using another IDE (e.g., JetBrains Rider), since the process will be similar
- .NET SDK
- C# Dev Kit extension for VS Code
Step 1: Prepare the project
Start by creating a new Blazor project.
In VS Code, you can use the command palette: Select “.NET: New Project…“, then “Blazor Web App“. Name your project (e.g., “BlazorDocumentScanner”), confirm the project directory, and select “Create project“.
Next, open Components/App.razor and add the script for including the Scanbot Web SDK from a CDN in the file’s body, below <script src="_framework/blazor.web.js"></script>.
<script src="https://cdn.jsdelivr.net/npm/scanbot-web-sdk@latest/bundle/ScanbotSDK.ui2.min.js"></script>
⚠️ Only import the SDK via a CDN for quick prototyping. In your production environment, download the Web SDK directly (or install it via npm) and include its files directly in your project. For Blazor, put them into wwwroot/wasm and update the enginePath property in the initialization code to /wasm/.
Step 2: Implement the document scanning functionalities
Create a new file wwwroot/js/scanbotSDKService.js, which will contain code for running the Scanbot Web SDK’s functions using Blazor’s JavaScript interop.
Open the file and add a method for initializing the SDK:
let scanbotSDK;
export async function initialize() {
try {
scanbotSDK = await ScanbotSDK.initialize({
licenseKey: "",
enginePath:
"https://cdn.jsdelivr.net/npm/scanbot-web-sdk@latest/bundle/bin/complete/",
});
console.log(scanbotSDK);
} catch (e) {
console.log(e.name + ": " + e.message);
}
}
Then also add a method for starting the document scanner:
export async function startDocumentScanner() {
const config = new ScanbotSDK.UI.Config.DocumentScanningFlow();
const result = await ScanbotSDK.UI.createDocumentScanner(config);
return result;
}
This will use the document scanner’s default configuration.
Step 3: Build the UI
Open Components/Pages/Home.razor (or another component of your choice) and replace the H1 and welcome text with a button that starts the document scanner.
<div class="row bg-white justify-content-center">
<div class="list-group">
<button type="button" class="list-group-item list-group-item-action" @onclick="StartScanDocument">Scan Document</button>
</div>
</div>
At the top of the file, inject the Blazor JavaScript interop service into the component and set its render mode to interactive server-side rendering.
@inject IJSRuntime JS
@rendermode InteractiveServer
Then, below the “Scan Document” button, use the interop mechanism to call the initialize function from scanbotSDKService.js.
@code {
private IJSObjectReference? jsObjectReference;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
try
{
jsObjectReference = await JS.InvokeAsync<IJSObjectReference>("import", "./js/scanbotSDKService.js");
if (jsObjectReference is not null)
{
await jsObjectReference.InvokeVoidAsync("initialize");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error invoking: {ex.Message}");
}
}
}
}
In addition, you need to call the startDocumentScanner function.
private async Task StartScanDocument()
{
try
{
if (jsObjectReference is not null)
{
await jsObjectReference.InvokeAsync<string>("startDocumentScanner");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error invoking: {ex.Message}");
}
}
Your final Home.razor file will look like this:
@page "/"
@inject IJSRuntime JS
@rendermode InteractiveServer
<PageTitle>Home</PageTitle>
<div class="row bg-white justify-content-center">
<div class="list-group">
<button type="button" class="list-group-item list-group-item-action" @onclick="StartScanDocument">Scan Document</button>
</div>
</div>
@code {
private IJSObjectReference? jsObjectReference;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
try
{
jsObjectReference = await JS.InvokeAsync<IJSObjectReference>("import", "./js/scanbotSDKService.js");
if (jsObjectReference is not null)
{
await jsObjectReference.InvokeVoidAsync("initialize");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error invoking: {ex.Message}");
}
}
}
private async Task StartScanDocument()
{
try
{
if (jsObjectReference is not null)
{
await jsObjectReference.InvokeAsync<string>("startDocumentScanner");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error invoking: {ex.Message}");
}
}
}
Now cd into your project directory and run the app to test your document scanner!
cd BlazorDocumentScanner
dotnet run

💡 To test your web app on your phone, you have a few options. One option is to use a service like ngrok, which creates a tunnel to one of its SSL-certified domains. The Quick Start guide will help you get up and running quickly.
Conclusion
🎉 Congratulations! You’ve successfully built a document scanning web app using Blazor!
If this tutorial has piqued your interest in integrating document scanning functionalities into your web app or website, make sure to take a look at the SDK’s other neat features in the documentation – or run our example project for a more hands-on experience.
Integration guides are also available for the following Web frameworks:
Should you have questions about this tutorial or run into any issues, we’re happy to help! Just shoot us an email via tutorial-support@scanbot.io.
Happy scanning! 🤳