Skip to content

feat: allow using IconifyJSON as custom collection#366

Merged
antfu merged 7 commits intonuxt:mainfrom
Aareksio:feature/custom-collections-in-client-bundle
Apr 10, 2025
Merged

feat: allow using IconifyJSON as custom collection#366
antfu merged 7 commits intonuxt:mainfrom
Aareksio:feature/custom-collections-in-client-bundle

Conversation

@Aareksio
Copy link
Copy Markdown
Contributor

@Aareksio Aareksio commented Mar 7, 2025

🔗 Linked issue

N/A

❓ Type of change

  • 📖 Documentation (updates to the documentation or readme)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • 👌 Enhancement (improving an existing functionality)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

📚 Description

Motivation
Using non-public IconifyJSON collections is common when working with premium icon sets or aiming for build optimizations by avoiding repetitive SVG parsing on each build.

Current issue
Currently, custom icon collections can be included using the serverBundle.collections option. However, this approach has significant drawbacks since it disables important nuxt-icon features such as server bundle auto-detection and client-side bundling.

Proposed solution
This PR updates nuxt-icon to recognize and properly handle IconifyJSON collections as custom collections. This ensures seamless integration, preserves all existing features (including auto-detection and client-side bundling), and provides a more robust solution for users who want to leverage private or optimized icon sets.

Major changes

  • customCollections now supports direct use of IconifyJSON objects
  • setting clientBundle.scan to true now also includes scanning for custom icon collections

Minor fixes

  • fixed an issue where icons from custom collections were not counted during client bundle preparation
  • resolved a bug causing icon data to ignore collection-level defaults when preparing the client bundle

In the playground, when includeCustomCollections: true is not set, nuxt-v3 icon without a prefix breaks. I suspect it may have something to do with useResolvedName, as a network call to nuxt.json?icon=v3 can be spotted when opening the playground.


This PR causes minimal conflicts with #360. I am willing to resolve them if needed.

@Aareksio Aareksio force-pushed the feature/custom-collections-in-client-bundle branch from 4f99b19 to 688f174 Compare March 7, 2025 18:17

function loadCollection(prefix: string) {
if (customCollectionNames.has(prefix)) {
const collection = customCollections.find(c => c.prefix === prefix)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.find should be alright here. We enter this path only once per custom collection. Optimizing lookup seems like an overkill for the sensible length of customCollections.

if (customCollectionNames.has(prefix)) {
const collection = customCollections.find(c => c.prefix === prefix)
if (collection) {
return Promise.resolve(collection)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the Promise.resolve here to keep the return type Promise<IconifyJSON | undefined> and play nicely with existing logic of iconifyCollectionMap.

Comment on lines +246 to +249
const data = getIconData(collection, name)
if (data) {
addIcon(collection.prefix, name, data)
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the change which properly merges icon settings with collection settings. Previously, each SVG icon had all the metadata (mostly width and height) embedded in its declaration. With IconifyJSON, it is common to keep common values on the collection level.

// SVG collection as loaded from `dir`
{
  prefix: 'svg',
  icons: {
    'nuxt-v2': { body: '...', height: 512, width: 512 },
    'nuxt-v3': { body: '...', height: 512, width: 512 },
  }
}

// _Optimized_ IconifyJSON for premium icon set
{
  prefix: 'optimized',
  icons: {
    'nuxt-v2': { body: '...' },
    'nuxt-v3': { body: '...' },
  },
  height: 512,
  width: 512,
}

@antfu antfu merged commit 9491b62 into nuxt:main Apr 10, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants