What is the best way to combine relative paths or create distinct identifiers for SVG files located within multiple layers of folders

I have a collection of icons exported from "Figma" organized in folders, and I'm using grunt-svgstore to create a sprite sheet. However, the result contains duplicated IDs even after trying 'allowDuplicateItems: false' and 'setUniqueIds: true' options.

Here is my folder structure:
-icons
--arrow
---arrow-left
----scale.svg
---arrow-right
----scale.svg
--checkbox
---active.svg
---inactive.svg
--chevron
---left-chevron
----scale.svg
---right-chevron
----scale.svg
--etc.

Snippet from Grunt file JS:

module.exports = function(grunt) {
grunt.initConfig({
    svgstore: { 
        options: {
            formatting : {
                indent_size : 2
            },
            includeTitleElement: false,
            preserveDescElement: false,
            allowDuplicateItems: false,
            setUniqueIds: true
        },
        default: {
            files: {
                'includes/defs.svg': ['icons/**/*.svg',]
            },
        },
    }
});  
grunt.loadNpmTasks('grunt-svgstore');  
};

Expected outcome based on relative path:

<svg>
  <symbol viewBox="0 0 32 32" id="arrow-arrow-left-scale">
    ...
  </symbol>
  <symbol viewBox="0 0 32 32" id="arrow-arrow-right-scale">
    ...
  </symbol>
</svg>

Actual result obtained:

<svg>
  <symbol viewBox="0 0 32 32" id="scale">
    ...
  </symbol>
  <symbol viewBox="0 0 32 32" id="scale">
    ...
  </symbol>
</svg>

Answer №1

I have discovered a new tool that perfectly meets my needs.

Here is the solution I found:

const zipName = 'icons.zip';
//Command: gulp default
const spriteFileName = 'icons_sprite';
const gulp = require('gulp');
const svgstore = require('gulp-svgstore');
const rename = require('gulp-rename');
const path = require('path');
const admZip = require('adm-zip');
const rimraf = require('rimraf');
const fs = require('fs');

gulp.task('default', function() {
  var zip = new admZip(zipName);
  zip.extractAllTo('./icons_sources/', false, true);
  return gulp
    .src('icons_sources/**/*.svg', {base: 'icons_sprite'})
    .pipe(
      rename(function(file) {
        var name = file.dirname.split(path.sep);
        if (file.basename === 'scale') {
          name = name.filter((n) => n !== '.' && n !== '..' && n !== 'icons_sources');
          file.basename = name.join('-');
        } else {
          name = name.filter((n) => n !== '.' && n !== '..' && n !== 'icons_sources');
          if (file.basename.search(/\d+x\d+/) >= 0) {
            file.basename = 'S' + file.basename.toUpperCase();
          }
        }
      })
    )
    .pipe(svgstore())
    .pipe(gulp.dest('src/assets/sprites'))
    .on('finish', () => {
      rimraf.sync('icons_sources');
      fs.unlinkSync(zipName);
    });
});

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

Are there any npm packages pre-installed in Azure functions? If there are, how can I verify their presence?

As I work on building my Azure function locally using WebStorm/PHPStorm, I am curious about if there are any pre-installed npm packages readily available in the cloud for Azure functions. It can be quite cumbersome to include all necessary packages each ...

Obtain the distinct highest value for every vertical axis on a bar graph

I'm facing an issue with my code where I am appending multiple SVG elements and generating 3 different charts. The problem is that the maximum value evaluated from the y.domain() for each y-axis is taken as the maximum value from all of my data. Is t ...

Ways to update a nested object by utilizing the setState method

I have a situation where I need to modify the key/value pairs of an object in my state. Specifically, I need to add a key/value pair to the object with an ID of 13. Please refer to the attached photo for reference. Although I know how to use setState, I ...

Quickly view products in Opencart will automatically close after adding them to the cart and redirecting the

I've integrated the product quickview feature into my OpenCart theme, which opens a product in a popup. However, when I add a product to the cart from the popup, it doesn't update on the main page until I refresh. I'm looking for a way to re ...

Enhancing AngularJS view rendering using ngshow

Currently, I am working on a view where ng-show is used to display a select DOM object when certain conditions are met, and an input DOM for all other scenarios. However, I have noticed that there is a significant delay in the disappearance of the input bo ...

The reducer I have is inexplicably returning undefined even though I'm certain it was added to combineReducers

After countless hours of debugging, everything seems to be in working order but the problem still persists. The main reducer file is located at reducers/index.js // @flow import { combineReducers } from "redux"; import blocks from "./blocks"; import user ...

Float: A threshold reached when adding 1 no longer has any effect

In the realm of programming, float serves as an estimation of a numeric value. For example, 12345678901234567890 === 12345678901234567891 evaluates to true However, 1234567890 === 1234567891 yields false Where does the equation num === num+1 reach a br ...

Utilize Require.js to Load Dropzone.js Library

I am interested in integrating Dropzone.js into an application that is built using Backbone and Require.JS. However, I am unsure of the correct implementation process. Should I utilize require()? What is the most effective way to handle this integration? ...

Is there a way to send a multi-dimensional array using jQuery ajax?

I am encountering an issue with posting an array as a JavaScript variable {{0,0},{1,1},{2,2}} using JSON.Stringify. Whenever I try to post it, I receive an internal server error 500. Can someone please advise on how I can successfully post and utilize this ...

Creating a realistic typewriter effect by incorporating Code Block as the input

I am looking to add a special touch to my website by showcasing a code segment with the Typewriter effect. I want this code block not only displayed but also "typed" out when the page loads. Unfortunately, I have been unable to find a suitable solution s ...

What is the process for dynamically setting @click in vue.js?

My array contains objects with methods as actions from a vue object. How can I dynamically set the @click event in a v-for loop? I attempted to use this.m1, "this.m1", "m1", but encountered an error: fns.apply is not a function. Javascript: new Vue ...

What is causing the error message "TypeError: expressJwt is not a function" to appear? Is there a way to resolve it and fix the issue?

Authentication with JWT in Node.js: const expressJwt = require('express-jwt') function setupAuth() { const secret = process.env.SECRET_KEY return expressJwt({ secret, algorithms: ['HS256'] }) } module.expor ...

What happens when arithmetic operators are applied to infinity values in JavaScript?

Why do Arithmetic Operators Behave Differently with Infinity in JavaScript? console.log(1.7976931348623157E+10308 + 1.7976931348623157E+10308)//Infinity console.log(1.7976931348623157E+10308 * 1.7976931348623157E+10308)//Infinity console.log(1.797693134 ...

Javascript enables dynamic field addition to tables

I have JSON data that needs to be displayed in an HTML table. To input the values, I have individual fields for firstname, lastname, email, and phone number, along with an "Add Row" button. When I click the "Add Row" button, I want the entered values to b ...

Developing a custom Node package in version 9.2.0 to provide compatibility with outdated Node releases

With the release of Node 9.2.0 and its new language features, I'm curious about how to develop a node module that remains compatible with older versions. For example, if I have a small module that is supported by Node 9 out of the box, like this: co ...

Unable to incorporate external JavaScript library into Laravel project

I'm facing a challenge in incorporating the bs treeview.js library into my Laravel project and need some guidance. Thus far, I have taken the following steps: npm install --save bstreeview I included require ('bstreeview'); in resources/js/ ...

The error message "Type Error: val.toString is not a function - mysql npm" indicates

I'm encountering an issue with the 'mysql' package in NPM on a nodeJS backend and I'm puzzled by this error message: TypeError: val.toString is not a function at Object.escape (/Applications/MAMP/htdocs/nodeJS_livredor/node_modules/sql ...

Tips for using ng-repeat in AngularJs to filter (key, value) pairs

I am trying to achieve the following: <div ng-controller="TestCtrl"> <div ng-repeat="(k,v) in items | filter:hasSecurityId"> {{k}} {{v.pos}} </div> </div> Code snippet for AngularJs: function TestCtrl($scope) { ...

Learn how to incorporate latitude and longitude coding into PHP to display a map icon that correctly redirects to the desired URL when clicked

I am in need of a table that includes buttons for adding, editing, deleting, and mapping. Everything works fine so far, but when I click on the map button, it should take me to Google Maps with coordinates linked from a MySQL database containing latitude ...

Is there a way to transmit a div using Node.js?

Scenario: I am developing a web application that allows users to draw on a canvas, save the drawing as an image, and share it with others using Node.js. Current Progress: Drawing functionality (real-time updates on both clients). Saving the canvas as a ...