strapi-plugin-dynamic-icons-field
Version:
A customizable plugin for Strapi to integrate an icons field into your content types.
248 lines (186 loc) • 6.31 kB
Markdown
# Strapi Plugin Dynamic Icons Field
A customizable plugin for Strapi 5 that dynamically loads icons from your Strapi collection into a custom field. Unlike static icon plugins, this plugin fetches icons directly from your content, eliminating the need for manual file management and deployments when adding new icons.
## ✨ Features
- **Dynamic Icon Loading**: Automatically loads icons from your Strapi `icons` collection
- **Server-Side Caching**: 5-minute memory cache with automatic invalidation when icons are modified
- **Flexible Storage**: Supports both local file storage (development) and Cloudinary (production)
- **Type Filtering**: Only loads icons with `type === "duotone icons"`
- **Performance Optimized**: Caches SVG content to minimize API calls
- **Auto Cache Invalidation**: Clears cache automatically when icons are created, updated, or deleted
## 🚀 Installation
### 1. Install the Plugin
```bash
npm install strapi-plugin-dynamic-icons-field
```
### 2. Configure the Plugin
Add the plugin to your `config/plugins.js`:
```javascript
module.exports = ({ env }) => ({
'dynamic-icons-field': {
enabled: true,
config: {
// Dynamic configuration handled by the plugin
},
},
// ... other plugins
});
```
**For local development** (if cloning the repo):
```javascript
module.exports = ({ env }) => ({
'dynamic-icons-field': {
enabled: true,
resolve: './src/plugins/strapi-plugin-dynamic-icons-field',
config: {
// Dynamic configuration handled by the plugin
},
},
// ... other plugins
});
```
### 3. Create Icons Collection
Create an `icons` collection type with the following fields:
```json
{
"kind": "collectionType",
"collectionName": "icons",
"info": {
"singularName": "icon",
"pluralName": "icons",
"displayName": "Icons"
},
"options": {
"draftAndPublish": false
},
"attributes": {
"label": {
"type": "string",
"required": true
},
"alt": {
"type": "string"
},
"type": {
"type": "enumeration",
"enum": ["light/dark icons", "duotone icons"],
"default": "duotone icons"
},
"icon": {
"type": "media",
"multiple": false,
"allowedTypes": ["images"]
}
}
}
```
### 4. Build and Restart
```bash
npm run build
npm run develop
```
## 📖 Usage
### Adding the Field to Content Types
1. Go to **Content-Type Builder**
2. Select your content type or component
3. Add a new field
4. Choose **Custom Field** → **Dynamic Icons Field**
5. Configure the field options:
- **Output**: Choose `name` or `svg` (what gets stored in the database)
- **Selection**: Optional - filter specific icons by name
### Adding Icons
1. Go to **Content Manager** → **Icons**
2. Create a new icon entry:
- **Label**: Display name for the icon
- **Type**: Set to "duotone icons"
- **Icon**: Upload your SVG file
3. Save the entry
The icon will automatically appear in all dynamic icons fields within 5 minutes (or immediately after cache invalidation).
## ⚙️ Configuration Options
### Field Configuration
When adding the field to a content type, you can configure:
- **Output Type**:
- `name`: Stores the icon label/name
- `svg`: Stores the SVG content
- **Selection Filter**: Comma-separated list of icon names to show (optional)
### Plugin Configuration
The plugin automatically handles:
- **Cache Duration**: 5 minutes (configurable in code)
- **Icon Filtering**: Only `type === "duotone icons"`
- **URL Resolution**: Automatic local/Cloudinary URL handling
## 🔧 Development
### Local Development Setup
1. Clone the repository
2. Install dependencies: `npm install`
3. Build the plugin: `npm run build`
4. Link to your Strapi project
### Building
```bash
npm run build
```
### Watching for Changes
```bash
npm run watch
```
## 🏗️ Architecture
### Server-Side Components
- **Controller**: Fetches icons from collection and SVG content from URLs
- **Routes**: Admin API endpoint `/dynamic-icons-field/icons`
- **Bootstrap**: Sets up lifecycle hooks for cache invalidation
- **Caching**: In-memory cache with automatic invalidation
### Frontend Components
- **IconSelect**: Main field component with dropdown selection
- **Icon**: SVG rendering component
### Data Flow
1. **Field Renders** → API call to `/dynamic-icons-field/icons`
2. **Server Checks Cache** → Return cached data or fetch fresh
3. **Database Query** → Find icons with `type === "duotone icons"`
4. **SVG Fetching** → Download SVG content from file URLs
5. **Response Caching** → Store processed icons in memory
6. **Frontend Display** → Render icons in dropdown
## 🔄 Cache Management
### Automatic Invalidation
Cache is automatically cleared when:
- Icons are created
- Icons are updated
- Icons are deleted
### Manual Cache Management
The cache can be manually cleared by restarting the Strapi server.
## 🌐 Environment Support
### Local Development
- Uses local file storage
- Constructs full URLs: `http://localhost:1337/uploads/file.svg`
### Production
- Supports Cloudinary URLs
- Uses full CDN URLs directly
## 🐛 Troubleshooting
### Icons Not Appearing
1. Check that icons have `type === "duotone icons"`
2. Verify SVG files are properly uploaded
3. Check server logs for fetch errors
4. Clear cache by restarting server
### Performance Issues
1. Check cache hit rates in server logs
2. Verify SVG files are not too large
3. Consider reducing cache duration for frequent updates
### Build Errors
1. Ensure all dependencies are installed
2. Check TypeScript compilation errors
3. Verify plugin registration in `config/plugins.js`
## 📝 License
MIT License - see LICENSE file for details.
## 🤝 Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests if applicable
5. Submit a pull request
## 📚 Changelog
### v0.1.3
- Initial release with dynamic icon loading
- Server-side caching implementation
- Automatic cache invalidation
- Support for local and Cloudinary storage
- Type filtering for duotone icons
## 🙏 Credits
Based on the original [strapi-plugin-icons-field](https://github.com/dupflo/strapi-plugin-icons-field) by Florian Dupuis.
Enhanced with dynamic loading capabilities by Marketing Developers.