I am working on a Blazor project in which I am using Bootstrap; which, of course, requires jQuery and Popper for the tooltips and popovers to work.
Originally, I just "manually" downloaded the required files:
- jQuery
- Popper
- Bootstrap (css and js)
and put them where they need to go:
- wwwroot/css
- wwwroot/js
The structure of wwwroot
looked like this:
/wwwroot
|
|- css/
| |
| |- bootstrap/
| |
| `- site.css
|
|- images/
|
`- js/
|
|- bootstrap/
|
|- jquery/
|
|- popper/
|
|- BootstrapJavascript.js
|
`- JavaScript.js
However, the "powers that be" have decided they would like to make this more efficient and automatic, so I now need to use LibMan to install everything, and I am using this method:
Solution Explorer -> Project -> Add -> Client-Side Library...
So, everything went smoothly when installing, however I am having trouble with Popper. After installing, wwwroot
now looks like this:
/wwwroot
|
|- css/
| |
| |- bootstrap*.*
| |
| `- site.css
|
|- images/
|
|- js/
| |
| |- bootstrap*.*
| |
| |- cjs/
| |
| |- esm/
| |
| |- umd/
| |
| `- BootstrapJavascript.js
|
`- scss/
And I am receiving errors indicating that the application cannot find certain libraries or components of libraries.
Originally, when using LibMan to install Popper, LibMan wanted to put Popper here:
wwwroot/lib/popper.js/
However, I elected to put Popper in:
wwwroot/js/
Also, on Bootstraps website, they instruct to pre-load the ability to use tooltips and popovers like this:
// For Bootstrap's Tooltips
// https://getbootstrap.com/docs/5.2/components/tooltips/
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]')
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl))
// For Bootstrap's Popovers
// https://getbootstrap.com/docs/5.2/components/popovers/
const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]')
const popoverList = [...popoverTriggerList].map(popoverTriggerEl => new bootstrap.Popover(popoverTriggerEl))
Which I have in my BootstrapJavascript.js file.
Some of the errors I am getting:
ReferenceError: exports is not defined
at https://localhost:5003/js/cjs/popper.js:7:23
Error at App.razor:line 48
, which is in here:
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await JSRuntime.InvokeAsync<IJSObjectReference>("import", "/js/cjs/popper.js"); // THIS IS LINE #48
await JSRuntime.InvokeAsync<IJSObjectReference>("import", "/js/bootstrap.js");
await JSRuntime.InvokeAsync<IJSObjectReference>("import", "/js/BootstrapJavaScript.js");
}
}
The application was working "perfectly" when I was hand installing Bootstrap, Popper, and jQuery, now it is not.
What do I need to do to get this working like when I was hand-installing?
EDIT:
libman.json
{
"version": "1.0",
"defaultProvider": "cdnjs",
"libraries": [
{
"library": "[email protected]",
"destination": "wwwroot/js/jquery/"
},
{
"library": "[email protected]",
"destination": "wwwroot/js/popper/"
},
{
"library": "[email protected]",
"destination": "wwwroot/"
}
]
}
App.razor
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await JSRuntime.InvokeAsync<IJSObjectReference>("import", "/js/jquery/jquery.min.js");
await JSRuntime.InvokeAsync<IJSObjectReference>("import", "/js/popper/cjs/popper.min.js");
await JSRuntime.InvokeAsync<IJSObjectReference>("import", "/js/bootstrap.min.js");
await JSRuntime.InvokeAsync<IJSObjectReference>("import", "/js/BootstrapJavaScript.js");
}
}
_Host.cshtml:
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="~/" />
<link rel="stylesheet" href="~/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
...
</div>
<script>
var blackpearlScript = document.createElement('script');
blackpearlScript.setAttribute('src', '/js/JavaScript.js');
document.head.appendChild(blackpearlScript);
</script>
</body>
2
Answers
I tried to fully explain the general solution that I use in my projects. Probably, your problem are in the definitions of js and css entries.
First of all install
LibMan
with the below command:The next step is to add a file called libman.json inside the project. To add this file, just enter the following command in the command prompt:
As you can see, we can also specify the package receiving source, which is set to cdnjs by default, and is actually a Content Delivery Network (CDN) for countless client-side packages. We can also enter our required packages in the libraries array. Even for each package, we can override the provider.
Now, you can get the Jquery, Bootstrap and so on by following command:
Finally, the libman.json file will have below structure:
After receiving its client-side packages, we will add the relevant entries to the Blazor Server application’s Pages
_Layout.cshtml
file (or to the Blazor WASM application’swwwroot/index.html
file).We define the entry of the css file in the head section and the js file before closing the body tag and of course before
<script src="_framework/blazor.server.js"></script>
in Blazor Server. There is no need to mention thewwwroot
starting folder; Becausebase href
is defined, it points to this folder.You can also use the
libman restore
command to reinstall the packages; In this case, just like Nuget, the packages will be downloaded from the libman.json file from the relevant provider and added to the project.One additional point: You can modify the program’s csproj file as follows to automatically run the libman restore command before the build:
EDIT:
According to your comment and edited question:
First, The bootstrap package is installed inside the root of
wwwroot
.However, it is referenced in the
JS
folder.Second, please remove the line below from _Host.cshtml:
I suggest that you try to refer to the
_Host.cshtml
file instead of referring to theOnAfterRenderAsync
method, such as below:You can do the same for other libraries, such as
Popper
.Please try this too. It means the default installation path (
/lib
) in thelibman
folder.I think that all the differences between the code of my project that is running now and the code of your project were these things.
First, I don’t know why you put your js files in
App.razor
, I think it is better ot add them in yourMainLayout.razor
or_Host.cshtml
:Second, I don’t think that you need to include Popper because Bootstrap has already this library in
bootstrap.bundle.js
, see this link. You can add this file like this:Solution Explorer -> right click on Project -> Add -> Client-Side Library -> twitter-bootstrap -> choose specific files -> js -> bootstrap.bundle.min.js.
Please note that the files will be added in
lib
folder, if you want to change the location, then you need to change yourlibman.json
and I don’t think that necessary to change location, just keep them inlib
folder.Then, your script in
MainLayout.razor
or_Host.cshtml
will be: