Are there alternative methods for utilizing ionicons without needing the <script> tag?

In our workplace, the designer opted to incorporate ionicons but the documentation only provides instructions on how to use them without Ionic:

Insert the following <script> at the end of your page, right before the closing </body> tag, to activate them.

<script type="module" src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="83eaecedeae0ecedf0c3b6adb6adb1">[email protected]</a>/dist/ionicons/ionicons.esm.js"></script>
<script nomodule src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4c252322252f23223f0c796279627e">[email protected]</a>/dist/ionicons/ionicons.js"></script>

To utilize a predefined icon from Ionicons package, specify the name attribute on the ion-icon component:

<ion-icon name="heart"></ion-icon>

However, this method requires a GET request to the CDN (unpkg.com), causing the icons to "flash" and shift the UI during loading.

Is there a way to utilize the NPM package and import it into the project to ensure instant loading of icons without affecting the UI?

I attempted the following in my svelte-kit project:

First attempt

<script>
  import "ionicons/dist/ionicons/ionicons.esm";
</script>

This resulted in the following error in my terminal:

TypeError: u.querySelector is not a function
    at Module.q (/node_modules/.pnpm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="99f0f6f7f0faf6f7ead9afb7a9b7ab">[email protected]</a>/node_modules/ionicons/dist/ionicons/p-9857dedb.js:3:6277)
    at eval (/node_modules/.pnpm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d9b0b6b7b0bab6b7aa99eff7e9f7eb">[email protected]</a>/node_modules/ionicons/dist/ionicons/ionicons.esm.js?v=642066af:4:162)
 ELIFECYCLE  Command failed with exit code 1.

Second attempt

<script>
  import "ionicons/dist/ionicons/ionicons.js";
</script>

This led to the following error:

ReferenceError: window is not defined
    at Object.<anonymous> (C:\Users\Carlos Daniel\Documents\code\jequi-frontend\node_modules\.pnpm\<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="bdd4d2d3d4ded2d3cefd8b938d938f">[email protected]</a>\node_modules\ionicons\dist\ionicons\ionicons.js:130:9)
    at Module._compile (node:internal/modules/cjs/loader:1101:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:190:29)
    at ModuleJob.run (node:internal/modules/esm/module_job:185:25)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:281:24)

Third attempt

<script>
  import { onMount } from "svelte";

  // no SSR
  onMount(async () => {
    await import("ionicons/dist/ionicons/ionicons.js");
  });
</script>

This produced an error in the browser's console:

GET http://localhost:3010/p-09cd4d8b.system.js net::ERR_ABORTED 404 (Not Found)

Uncaught (in promise) Error: Error loading http://localhost:3010/p-09cd4d8b.system.js at HTMLScriptElement.<anonymous> (ionicons.js:107:2894)

Fourth attempt

<script>
  import { onMount } from "svelte";

  // no SSR
  onMount(async () => {
    await import("ionicons/dist/ionicons/ionicons.esm");
  });
</script>

This resulted in an error in the browser's console:

Uncaught (in promise) TypeError: Failed to construct 'URL': Invalid URL
    at ionicons.esm.js:1:109
    at ionicons.esm.js:1:134

and another one in my terminal:

344|  var J = (e2) => {
345|    const t2 = e2.o.replace(/-/g, "_"), n2 = e2.U, l2 = I.get(n2);
346|    return l2 ? l2[t2] : import(`./${n2}.entry.js`).then((e3) => (I.set(n2, e3), e3[t2]), G);
   |                                ^
347|  };
348|  var K = /* @__PURE__ */ new Map();
The above dynamic import cannot be analyzed by vite.
See https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#limitations for supported dynamic import formats. If this is intended to be left as-is, you can use the /* @vite-ignore */ comment inside the import() call to suppress this warning.

Soooo....

Any suggestions on how to resolve this issue? I prefer not to rely on a CDN due to the UI shifting during loading, and unfortunately, switching to a different icon library is not an option as my boss is firm on sticking with ionicons.

I am aware of some packages designed for svelte, but they are unofficial and their implementation seems cumbersome. I've used them in previous projects and managing all the imports was challenging.

Thank you in advance!

Answer №1

An effective method for handling this issue involves utilizing source vector files, typically in SVG format, and converting them into Svelte components using a script automation process. The seamless conversion of SVGs to Svelte components is made possible due to their compatibility.

If you are dissatisfied with existing solutions such as svelte-ionicons, you may need to create your own solution.

Alternatively, you can opt to develop or utilize a custom loader that can directly embed the SVGs or import them into your components based on the build tool being used.

(The SVG files come pre-packaged within the package under ionicons/dist/svg)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

When using Vue, the image element may not display the value stored in the object property

Excuse me for being new to Vue and struggling a bit. I'm attempting to display an image using a src that comes from an object property, which is retrieved from an array returned by data() I am not receiving any errors, but the icon is not appearing. ...

A guide to programmatically downloading a file with JavaScript on Internet Explorer

I'm currently facing a challenge with my web page. There is a button that, when clicked, should generate a CSV file (by converting from JSON) for the user to download. I've implemented the logic based on this jsfiddle, and it works perfectly in C ...

"Capturing the essence of your online presence: The

I recently completed a website for my Students Organization, which includes a special page dedicated to recognizing the individuals who helped organize our activities. Each member is represented with a photo on this page, sourced from their Facebook profil ...

Utilizing AngualarJS to bind data to intricate objects using the $resource functionality

Currently, I am working on a restful service that retrieves an order along with a list of items. In my project, I am developing a screen where users can edit specific items within the order. To achieve this, I need to display the list of items before locat ...

Utilize the synchronization feature of ES6 Promises in Jasmine with the then/catch method

I have an angular controller that needs to be tested. This controller utilizes a service to fetch data from a server, and the service returns ES6 Promises. function MyController($scope, MyService) { $scope.doSomething = function () { MyService.foo() ...

JavaScript - Employing the .every function with an array containing objects

Is it possible to use the array.every method on multidimensional arrays? The structure of my array is as follows: tabs=[ {label: string, icon: icon, routerLink: link}, {label: string, icon: icon, routerLink: link}, {label: string, icon: icon, routerLink: ...

To successfully import files in Sveltekit from locations outside of /src/lib, make sure to include the .ts extension in the import statement

Currently, I am working on writing tests with Playwright within the /tests directory. I want to include some helper functions that can be placed in the /tests/lib/helpers folder. When the import does not specifically have a .ts extension, tests throw a mo ...

Discovering elements using Selenium in a JavaScript popup box

The issue at hand is rather straightforward. I am faced with the task of clicking on an element within a popup that has been dynamically generated by JavaScript code. The challenge arises as the page is solely accessible in Internet Explorer and the elemen ...

Retrieving a boolean value (from a JSON file) to display as a checkbox using a script

Currently, I am utilizing a script to fetch data from a Google Sheet $.getJSON("https://spreadsheets.google.com/feeds/list/1nPL4wFITrwgz2_alxLnO9VBhJQ7QHuif9nFXurgdSUk/1/public/values?alt=json", function(data) { var sheetData = data.feed.entry; va ...

I am looking to share videos and large files without the use of a flash plugin

Looking for a way to upload videos without using the Flash Plugin and without relying on the browser's default browse button, especially for large files. It would be great to have a progress bar displayed during the upload process. Alternatively, is ...

Exploring a nested JSON structure using AngularJS's Ng-Repeat directive

I am facing an issue with displaying all elements of subcategory using Ng-Repeat. I have managed to show all events from the selected category with this code, but I am unsure how to display all activities from a specific event. I currently have this code.. ...

Eliminate lower values in select 1 if the value selected in select 2 is higher

I am struggling with a particular piece of code and could really use some assistance. Within my project, I have two select boxes. The first box allows users to select the "from" year, while the second box is for selecting the "to" year. What I'm tryi ...

Updating radio button based on selection change in jQuery

I'm struggling with jQuery and can't seem to figure out how to change the selected radio button based on a value in another select box. <div class="radio-inline" id="sourceDiv" role="group"> <input type="radio" id="sourceBtns1" na ...

Issue with a stationary directional light tracking the movement of a rotating object and/or changes in the camera perspective

I've been facing a challenge in implementing a day-night cycle with a directional light in an Earth model using custom shaders. Everything seems to work fine with the night and day maps, as well as the light, as long as I don't manipulate the cam ...

Guide to continuously polling a GET request in JavaScript until the response status is successful

In my JavaScript code, I have a function that utilizes AJAX to send a GET request. The response from the request can be either success, fail, or in process if the job is still running. I want this function to continuously send the GET request every few s ...

looking to showcase the highest 'levelNumber' of elements within an array

arr1 = [ { "levelNumber": "2", "name": "abc", }, { "levelNumber": "3", "name": "abc" }, { "levelNumber": "3", "name": &quo ...

Struggling to comprehend the node.js walker concept

I am struggling to grasp the concept of how the signature/header of the node.js walker functions. I understand that a walker can go through a directory and apply filters, but I'm unsure about how the signature of the .on function works. For example: ...

Tips for increasing the height of a popover when clicked

When a user focuses on the password input, a popover displays information. At the bottom of the popover, there is a link. How can I make the popover expand when the user clicks on this link? I have tried adding an !important class for the height value, us ...

Exploring and accessing the properties of objects in JavaScript

While attempting to access the email and password fields, an unexpected '0' seems to have appeared. The object retrieved from RethinkDB appears fine without this '0'. However, when using Lodash's _.assign() method like so: var use ...

System CSS modules do not work correctly with Reactjs, CRA, TS, and Carco when using Less

Issues have arisen with the CSS module system in my project. Below are snippets from various code files and configurations: react-app-env.d.ts, craco.config.js, CircleButtonWithMessage.module.less, CircleButtonWithMessage.tsx, as described below: //react-a ...