Blazor

Server y WebAssembly, con JS interop para identificar desde C#.

Antes de empezar

  • Una app Blazor Server o WebAssembly (.NET 8)

1. Agregá el script al host

En Blazor Server el archivo es Components/App.razor (o Pages/_Host.cshtml en .NET 7). En WebAssembly es wwwroot/index.html.

En ambos casos va antes de </body>, después del script de Blazor.

Components/App.razor
    <script src="_framework/blazor.web.js"></script>    <script>        window.TinkaySettings = { token: "pk_live_xxx" };    </script>    <script src="https://cdn.tinkay.app/widget.js" async></script></body>

2. Servicio de interop

Envolvé la API del widget en un servicio para llamarla desde cualquier componente.

Services/TinkayInterop.cs
using Microsoft.JSInterop;namespace MyApp.Services;public class TinkayInterop(IJSRuntime js){    public ValueTask OpenAsync() => js.InvokeVoidAsync("Tinkay.open");    public ValueTask CloseAsync() => js.InvokeVoidAsync("Tinkay.close");    public ValueTask IdentifyAsync(TinkayVisitor visitor) =>        js.InvokeVoidAsync("Tinkay.identify", visitor);}public record TinkayVisitor(string Email, string Name, string? Plan = null){    public string email => Email;    public string name => Name;    public string? plan => Plan;}

3. Identificar tras el render

La interop de JavaScript solo está disponible después del primer render. Usá OnAfterRenderAsync con la guarda firstRender.

Components/Layout/MainLayout.razor
@inherits LayoutComponentBase@inject TinkayInterop Tinkay@inject AuthenticationStateProvider AuthProvider@Body@code {    protected override async Task OnAfterRenderAsync(bool firstRender)    {        if (!firstRender) return;        var state = await AuthProvider.GetAuthenticationStateAsync();        var user = state.User;        if (user.Identity?.IsAuthenticated != true) return;        await Tinkay.IdentifyAsync(new TinkayVisitor(            Email: user.FindFirst(ClaimTypes.Email)?.Value ?? "",            Name: user.Identity.Name ?? "",            Plan: user.FindFirst("plan")?.Value));    }}

En Blazor Server, OnAfterRenderAsync corre cuando el circuito está listo. Llamar a la interop antes lanza InvalidOperationException.

Abrir el Messenger desde un botón

Components/Pages/Ayuda.razor
@inject TinkayInterop Tinkay<button class="btn btn-primary" @onclick="AbrirSoporte">Hablar con soporte</button>@code {    private async Task AbrirSoporte() => await Tinkay.OpenAsync();}

Verificar la instalación

Entrá a Configuración, Instalación en tu workspace, pegá la URL pública del sitio y tocá Probar instalación. Tinkay busca el script y valida que el dominio esté permitido.

  1. Abrí tu sitio en una pestaña nueva y confirmá que aparece el botón flotante.
  2. En la consola del navegador, escribí window.Tinkay y verificá que devuelve un objeto.
  3. Escribí un mensaje de prueba y confirmá que llega al Inbox.

Errores frecuentes

  • El widget no aparece: el dominio no está en Configuración, Dominios. Agregalo y recargá.
  • Aparece en desarrollo pero no en producción: agregá también el dominio de producción, incluida la variante con www.
  • Content Security Policy: permití https://cdn.tinkay.app en script-src y https://app.tinkay.app en frame-src y connect-src.
  • `Tinkay is not defined`: el loader todavía no terminó de cargar. Llamá a la interop en OnAfterRenderAsync y no en OnInitializedAsync.
  • WebAssembly y prerender: si usás prerendering, la identificación debe correr en el render interactivo, no en el prerender.

Cómo saber que quedó bien

  • El botón aparece tras el primer render.
  • `TinkayInterop.IdentifyAsync` no lanza excepción y el Inbox muestra al usuario.