Call JavaScript from C#
A JavaScript contract is declared in C# and implemented by the web UI. Vidra generates both the C# caller and the TypeScript handler registry.
The scaffold includes a runnable counter example.
Declare the JavaScript contract
using Vidra.Bridge;
namespace MyApp;
[JsContract("counter")]
public interface ICounterJs
{
[JsMethod("increment")]
Task<int> IncrementAsync();
}
The interface is the source of truth. Methods may accept one typed payload and
must return Task or Task<T>.
Build the generated APIs
npm run dev
The build generates:
- A typed
Counterclient available fromBridge.Js()in C#. counterHandlersinui/src/generated/index.ts.- A manifest entry and fingerprint covering the method signature.
Implement the handler in JavaScript
Register the handler when the UI mounts and unsubscribe when it unmounts:
import { counterHandlers } from "./generated/index.js";
let count = 0;
const unsubscribe = counterHandlers.increment(() => {
count += 1;
return count;
});
// Later:
unsubscribe();
In React:
const countRef = useRef(0);
useEffect(() => {
return counterHandlers.increment(() => {
countRef.current += 1;
setCount(countRef.current);
return countRef.current;
});
}, []);
The generated signature enforces the payload and return type. Async handlers are supported by returning a promise.
Invoke JavaScript from C#
Call the generated client from a VidraPage:
private async Task OnTickAsync()
{
var count = await Bridge.Js().Counter.IncrementAsync();
System.Diagnostics.Debug.WriteLine($"Counter is now {count}");
}
Vidra correlates the request with the JavaScript result and surfaces a missing or failed handler as a bridge error.
Choosing a direction
- Use a native contract when JavaScript requests work from C#.
- Use a JavaScript contract when C# needs a result from JavaScript.
- Use an event contract when C# broadcasts a notification and does not need a response.
Continue with Send events to JavaScript or read Code generation for the complete pipeline.