themasterchief
themasterchief

Reputation: 361

Embed Github Gists in the Blazor Web assembly component

How can I embed Github Gists into a Blazor Web assembly app? I can't figure out how to render the embed script tags into the component.

What I'm trying to do is to add the embed script link from Github Gist and into my web app.

enter image description here

IDE complains that tags cannot be added to a component and throws the following error

enter image description here

I have tried using the JSInterop but even that doesn't work.

Thanks in advance

Upvotes: 0

Views: 79

Answers (1)

fingers10
fingers10

Reputation: 7947

Here is how I did it.

GithubGistSnippet.razor:

@inherits GithubGistSnippetBase

<section class="[ flex flex-col ]">
    <h4 class="[ bg-gray-200 ] [ p-2 ] [ font-semibold ] [ text-black ] [ flex items-center ]">
        <svg xmlns="http://www.w3.org/2000/svg" class="[ icon icon-tabler icon-tabler-code ] [ text-purple-700 ] [ fill-purple-500 ]" width="20" height="20" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
            <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
            <polyline points="7 8 3 12 7 16"></polyline>
            <polyline points="17 8 21 12 17 16"></polyline>
            <line x1="14" y1="4" x2="10" y2="20"></line>
        </svg> Code Sample - @Title
    </h4>
    <article id="@Id" class="[ bg-gray-300 ]">
    </article>
</section>

GithubGistSnippet.razor.cs:

using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;

namespace Web.Components;

public class GithubGistSnippetBase : ComponentBase, IAsyncDisposable
{
    private IJSObjectReference? module;

    protected string Id = Guid.NewGuid().ToString();

    [Inject] private IJSRuntime JSRuntime { get; set; } = default!;

    [Parameter, EditorRequired] public string Title { get; set; } = default!;
    [Parameter, EditorRequired] public string UserId { get; set; } = default!;
    [Parameter, EditorRequired] public string FileName { get; set; } = default!;

    protected override async Task OnInitializedAsync()
    {
        module = await JSRuntime.InvokeAsync<IJSObjectReference>("import", "./js/githubgist.js");

        await module.InvokeVoidAsync("printSnippetFrom", Id, UserId, FileName);
    }

    async ValueTask IAsyncDisposable.DisposeAsync()
    {
        if (module is not null)
        {
            await module.DisposeAsync();
        }
    }
}

githubgist.js:

export function printSnippetFrom(id, userId, filename) {
    const target = document.getElementById(id);
    const iframe = document.createElement('iframe');
    const iframeId = `${userId}-${filename}`;
    iframe.setAttribute("id", iframeId);
    iframe.setAttribute("width", "100%");
    target.appendChild(iframe);

    let doc = iframe.document;
    if (iframe.contentDocument) doc = iframe.contentDocument;
    else if (iframe.contentWindow) doc = iframe.contentWindow.document;

    const gistScript = `<script src="https://gist.github.com/${userId}/${filename}.js"></script>`;
    const resizeScript = `onload="parent.document.getElementById('${iframeId}').style.height=document.body.scrollHeight + 'px'"`;
    const iframeHtml = `<html><body ${resizeScript}>${gistScript}</body></html>`;

    doc.open();
    doc.writeln(iframeHtml);
    doc.close();
}

Usage:

<GithubGistSnippet Title="DeSerialization" UserId="fingers10" FileName="44eb8a5a5427b472d1c48ecb1b4268f7"></GithubGistSnippet>

Output: GithubGistSnippet Component Output

Upvotes: 1

Related Questions