In blazor i use NavigationManager.NavigateTo(url)
in order to change window location, but how can I use it to open a new tab with a specified URL without having to invoke JS on OnAfterRenderAsync()

- 234,701
- 27
- 340
- 448

- 407
- 1
- 4
- 10
6 Answers
As of 1 of June 2022 there is no way of currently doing it directly with pure Blazor, you'll need to use JSInterop. Luckily this is easy enough to do. At the top of your .razor
file add
@inject IJSRuntime JSRuntime;
And then use it like so
await JSRuntime.InvokeAsync<object>("open", url, "_blank");
Note that the IJSRuntime
interface itself only provides a InvokeAsync<TValue>
method, the JSRuntimeExtensions
class provides an extension method for IJSRuntime
to directly invoke a method without a return value: InvokeVoidAsync
await JSRuntime.InvokeVoidAsync("open", url, "_blank");

- 7,193
- 24
- 47
-
Rollback to revision 1 as [IJSRuntime does not have `InvokeVoidAsync`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.jsinterop.ijsruntime.invokeasync?view=aspnetcore-3.1) – MindSwipe Jul 07 '20 at 07:08
-
do I have to use in in `OnAfterRender` or can I run it from an onclick? – Flexy Jul 07 '20 at 12:20
-
also the Js opens a new window only when i click somewhere inside the page, it does not execute automatically in method: `await JsRuntime.InvokeAsync – Flexy Jul 07 '20 at 12:28
-
You should be able to call the code anywhere, but I'd recommend `OnClick` because else most browsers will block it as it may not be a user initiated event – MindSwipe Jul 07 '20 at 12:39
-
3This does work, however eventually a TaskCanceledException will be thrown. I guess I can catch and ignore it, I am just wondering if there is a way to prevent the exception? – StefanFFM Oct 07 '20 at 09:00
-
1Is there a way to prevent TaskCanceledException? – Suresh Tadisetty May 19 '21 at 02:11
-
@SureshTadisetty I honestly have no idea, I haven't ever really done anything with Blazor, and even the little bit I did is now almost a year ago – MindSwipe May 20 '21 at 14:52
-
Note that using InvokeVoidAsync avoids the TaskCanceledException; answer has been updated – user3071284 Jun 13 '22 at 16:23
-
@user3071284 problem is that `InvokeVoidAsync` isn't specified on the `IJSRuntime` interface. I updated the answer to add that part. Plus, I don't see how `InvokeVoidAsync` avoids the exception, even after looking at [the source code](https://github.com/dotnet/aspnetcore/blob/b20ced25209e70402c5a8f8f9ff174461d0bb353/src/JSInterop/Microsoft.JSInterop/src/JSRuntimeExtensions.cs#L22). Maybe it was fixed internally somewhere between I originally posted this answer and today – MindSwipe Jun 15 '22 at 08:44
-
@MindSwipe I do see `InvokeVoidAsync` as an extension method. Using it does prevent the `TaskCanceledexception` that was occurring about a minute after invocation, in my case at least. https://learn.microsoft.com/en-us/dotnet/api/microsoft.jsinterop.jsruntimeextensions.invokevoidasync – user3071284 Jun 16 '22 at 14:41
-
@user3071284 hmm, funny. I'll try and reproduce it locally and see why the extension method doesn't throw an exception – MindSwipe Jun 20 '22 at 06:48
Formerly, this code worked.
await _jsRuntime.InvokeVoidAsync("open", new object[2] { url, "_blank" });
At present, it now results in an uncaught exception:
> "TypeError: Converting circular structure to JSON
I found this behavior explained here (https://github.com/dotnet/aspnetcore/issues/16632):
This is because window.open returns a WindowProxy object (see https://developer.mozilla.org/en-US/docs/Web/API/Window/open). WindowProxy is not JSON-serializable, so can't be used as a return value to .NET code.
To fix this, don't call window.open directly, but instead call a JS function of your own that either returns nothing or returns something that is JSON-serializable.
Per the above recommendation, I added the following to index.html:
<script>
window.blazorOpen = (args) => {
window.open(args);
};
</script>
And modified my C# code-behind call to pass the window arguments:
await _jsRuntime.InvokeVoidAsync("blazorOpen", new object[2] { url, "_blank" });
Effectively we now avoid the issue by discarding the WindowProxy object returned by window.open, which was formerly returned to InvokeVoidAsync and .NET was attempting to (unsuccessfully) process.

- 2,035
- 1
- 16
- 16
You will get TypeError: Converting circular structure to JSON
when using
await _jsRuntime.InvokeVoidAsync("open", new object[2] { url, "_blank" });
or
await _jsRuntime.InvokeAsync<object>("open", url, "_blank");
This is because
window.open
returns aWindowProxy
object (see https://developer.mozilla.org/en-US/docs/Web/API/Window/open).WindowProxy
is not JSON-serializable, so can't be used as a return value to .NET code.
Taken from see here.
To get around this w/o using a javascript function, I use the following
await JSRuntime.InvokeVoidAsync("eval", $"let _discard_ = open(`{url}`, `_blank`)");

- 311
- 3
- 5
-
Thank you, it really helped though not sure if currently eval can be used (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#never_use_eval!) – Guru_07 Aug 07 '21 at 14:35
Just use a regular link
<a href="@Url" target="_blank">@UrlDescription</a>

- 7,452
- 1
- 20
- 35
-
i want to open a window from a C# function in blazor `@onclick` event handler – Flexy Jul 07 '20 at 13:43
-
-
-
I'm confused by your design. You want them to click something but it can't be an element designed to do what you ask? Anyway, glad you are happy. – Mister Magoo Jul 08 '20 at 11:21
-
well a link is generated by c# within that function and then user is redirected to that url – Flexy Jul 08 '20 at 12:07
-
Right, but you know the URL, you can emit that into the html and avoid any extra code just to navigate? – Mister Magoo Jul 08 '20 at 12:51
-
C# generates a link in `@onclick`, which is a "pay" button, the link redirects to the payout page with certain tokens, now I could generate the link, then ask the user to click on another element, but that would require 2 clicks instead of 1 – Flexy Jul 08 '20 at 12:54
-
Both InvokeAsync and InvokeVoidAsync will "work"/execute, but after opening the window will throw an Uncaught TypeError: Converting circular structure to JSON. – Mike Sep 29 '20 at 12:13
-
Per the latest change in API here is the working solution where you can add any custom object attribute to the URL as shown below:
/// <summary>
/// Show Link
/// </summary>
/// <returns></returns>
private async Task ShowLink()
{
if (this.selectedItem != null)
{
string url = $"https://example.com/sites/" + this.selectedItem.Id + "/SitePages/Reports/somepage.aspx";
//NavigationManager.NavigateTo(url, false);//opens the new page on same browser tab
string[] values = { url, "_blank" };
CancellationToken token = new CancellationToken(false);
await JSRuntime.InvokeAsync<object>("open", token, values);//opens the link in new browser tab
}
}

- 201
- 2
- 3
The best way is to:
<NavLink class="MyCssClass"
target="_blank"
href="https://www.google.com">
Google in new window
</NavLink>

- 184
- 1
- 8
-
(I know, hijacking the thread ) Tip: If you are using this example (you are ok with regular anchor tag) you can get the full URL from the NavigationManger.ToAbsoluteUri, - f ex in a list of items like this : – JimiSweden Mar 31 '23 at 16:54