In this article, we are going to learn how we can Copy to Clipboard in a Blazor WebAssembly Project.
Let’s start.
When building applications, we may want to provide the ability to automatically copy data to a user’s clipboard on a button click, such as copying a code snippet or other useful information that would otherwise require the user to highlight and select copy.
Unfortunately, Blazor doesn’t directly provide the functionality for copying data to the clipboard. However, we can incorporate some JavaScript using the JSInterop.
When working in a browser, we get access to the JavaScript Clipboard API, which allows us to easily write data to the clipboard.
Now that we understand what we need to create for our Copy to Clipboard functionality, let’s start by creating a project.
We start by creating a Blazor WebAssembly project by using the template provided by Visual Studio or using the dotnet new blazorwasm
command.
We can go ahead and remove any of the boilerplate code generated, ensuring we leave Index.razor
in the Pages folder, along with the components in the Shared folder.
We are going to create a couple of components to demonstrate different scenarios, so let’s create a service that can be injected into our components and reused as needed.
Let’s start by creating IClipboardService
:
public interface IClipboardService { Task CopyToClipboard(string text); }
Next, we create an implementation for this interface:
public class ClipboardService : IClipboardService { private readonly IJSRuntime _jsInterop; public ClipboardService(IJSRuntime jsInterop) { _jsInterop = jsInterop; } public async Task CopyToClipboard(string text) { await _jsInterop.InvokeVoidAsync("navigator.clipboard.writeText", text); } }
First, we need to inject IJSRuntime
. This allows us to interact with JavaScript in our C# code.
In CopyToClipboard()
we call InvokeVoidAsync()
, passing navigator.clipboard.writeText
as our first parameter, which will call the JavaScript function.
Finally, we pass our text
parameter as the text we want to write to the clipboard.
We also need to register this service as a scoped service in the Program
class:
builder.Services.AddScoped<IClipboardService, ClipboardService>();
This covers the basic logic we need to copy data to the clipboard.
We have a service that handles our Copy to Clipboard logic, so now we want to create a component that can be re-used in our application:
@inject IClipboardService ClipboardService <button @>We start by injecting our
IClipboardService
.Then we create a
button
element, adding an event handler for theonclick
event. In our@code
block, we create aTextToCopy
parameter. We also add aclass
attribute, providing some Bootstrap classes.Finally, we create an
OnClick()
method, that will callCopyToClipboard()
and pass theTextToCopy
parameter.Next, let’s create a component that we can use later to verify if our Copy to Clipboard logic is working correctly.
Create a Component to Show the Copied Text
We can verify that our Copy to Clipboard logic works as expected by simply creating a
textarea
to paste our data into:<p>Paste text here: </p> <textarea rows="10" cols="50"></textarea>We create a simple paragraph to show the user what to do, along with a
textarea
element to allow users to paste data from their clipboard to verify the logic is working.With this created, we can now look at some of the scenarios we could come across that would require the use of this component.
Single-line Copy to Clipboard
The first scenario in which we may wish to use our Copy to Clipboard component is when we have a single line of read-only text that the user would like to copy, such as a website or a repository URL.
Let’s create a component for this scenario:
@page "/singleline" <h3>Singe-line Copy to Clipboard</h3> <input type="text" readonly value="@text" /> <CopyToClipboard TextToCopy="@text" /> <TextArea /> @code { string text = "Some readonly text to copy"; }Initially, we use the
@page
directive to mark this component as a routable component.Then we create an
input
element, making sure to include thereadonly
attribute. We set the value to thetext
field that we define in our@code
block.Next, we include the
CopyToClipboard
component that we’ve created previously, passing thetext
field to theTextToCopy
parameter.Finally, we add the
TextArea
component defined previously to verify the Copy to Clipboard logic works as expected.Multi-line Copy to Clipboard
Sometimes we may have a multi-line value that we would like to copy, such as a code snippet. We can use our
CopyToClipboard
component to provide this functionality:@page "/multiline" <h3>Multi-line Copy to Clipboard</h3> <textarea readonly rows="3" cols="10">@text</textarea> <CopyToClipboard TextToCopy="@text" /> <TextArea /> @code { string text = @"This is a multiline code snippet"; }Once again, we start by defining the route for this component.
This time, we create a
textarea
element, which allows for multi-line text input. Again, we use thereadonly
attribute. Within thetextarea
element, we place thetext
field defined in our@code
block. This time we use the verbatim string to create a multiline text.The final steps are the same as before. We add our
CopyToClipboard
component, passing in the text field to theTextToCopy
parameter. Finally, we add theTextArea
component.Copy User Input
A final scenario where we can provide a Copy to Clipboard button would be when we ask the user for input in the form of an
input
ortextarea
element.Let’s create a component for that:
@page "/userinput" <h3>User input Copy to Clipboard</h3> <input @bind-value="text" /> <CopyToClipboard TextToCopy="@text" /> <TextArea /> @code { string text = ""; }We start by creating this component routable with the
@page
directive.Then, we define an
input
element, using the@bind-value
attribute to bind to thetext
field we create in the@code
block.Finally, we add the
CopyToClipboard
andTextArea
components.Define the Navigation Links
Before we test the Copy to Clipboard functionality, let’s add our routable components to the
NavMenu
component:<div class="nav-item px-3"> <NavLink class="nav-link" href="singleline"> <span class="oi oi-list-rich" aria-hidden="true"></span> Single-line </NavLink> </div> <div class="nav-item px-3"> <NavLink class="nav-link" href="multiline"> <span class="oi oi-list-rich" aria-hidden="true"></span> Multi-line </NavLink> </div> <div class="nav-item px-3"> <NavLink class="nav-link" href="userinput"> <span class="oi oi-list-rich" aria-hidden="true"></span> User Input </NavLink> </div>We add 3
NavLinks
to the existingNavMenu
, ensuring to set thehref
for each of the components we created.Test Copy to Clipboard Functionality
We have everything we need to test our functionality, so let’s run our application and navigate to
/singleline
first and then click our Copy to Clipboard button:Placing our cursor in the
textarea
, we can verify our Copy to Clipboard functionality works by pressingCtrl + V
or right-clicking and selecting Paste:Next, we’ll test a multi-line
textarea
, by navigating to/multiline
and running the same test:Once again, we can verify that our functionality works as expected:
Style the Copy to Clipboard Component
So far, the user has no way of confirming if the data has been copied to their clipboard, without attempting to paste it. So let’s provide some visual feedback to let the user know the data has been successfully copied to their clipboard.
Let’s revisit our
CopyToClipboard
component and add some extra logic:@inject IClipboardService ClipboardService <button @>First, we change the
class
attribute to ourbutton
element, binding it to thebuttonClass
field we define in the@code
block. Also, we set the button text to thebuttonText
field.Then, we define some string constants, for the different states we want to set the button class and text in. We must remember to set the initial state of our button text and class to the
_copyToClipboardText
and_defaultClass
fields.This time, in the
OnClick()
method, once the text has been copied to the clipboard, we setbuttonText
to_copiedToClipboard
field, andbuttonClass
to_successClass
. We need to remember to call theStateHasChanged
method to re-render our button.Finally, We put in a 2-second delay and reset our button to the normal state.
Let’s run the application and navigate to
/userinput
to see our changes in action:This time around, when we click the button, the text and color change as we specified. After 2 seconds, the text and color will revert to the original ones. We can also confirm our user input component works as expected:
Conclusion
Now we know how to implement Copy to Clipboard in Blazor WebAssembly applications. This feature is very useful for complex or very long areas of data, such as URLs or code snippets, where we want to provide the user with an easy way to copy this data to their clipboard.
HttpClient and RestSharp are HTTP Client libraries that we can use to consume APIs. Working…
Unit Testing is extremely important for creating robust software. It's very simple in principle but…
Have you ever needed to sort a list of items, but didn't want to use…
In ASP.NET Core dependency injection, we usually register injectable dependencies at the start of our…
In this article, we are going to learn more about ranges and indices in C#,…
Issue #128 of the Code Maze weekly. Check out what's new this week and enjoy…
View Comments
Hi,
I tried this and it work Perfect
JSRuntime.InvokeVoidAsync("navigator.clipboard.writeText", {String to Copy});