How Can I Add Custom SVG Icons to the <select-icon /> Interface in Directus?

Hey all,

I’m working on extending the functionality of the <select-icon /> interface in Directus and I need some guidance on how to implement the following:

  • Add my own custom SVG icons
  • Display them inside the existing icon picker interface (<select-icon />)

Note: This is a custom build of Directus.


What I’ve Tried So Far

custom-icons.ts

interface CustomIcon {
  name: string;
  width: number;
  height: number;
  paths: {
    d: string;
    fill?: string;
    stroke?: string;
  }[];
}

export const customIcons: Record<string, CustomIcon> = {
  my_icon: {
    name: 'my_icon',
    width: 24,
    height: 24,
    paths: [
      {
        d: 'M12.5 11.5L8.5 15.5L10 17M12.......',
        stroke: '#EBE5DF',
        'stroke-width': 1.5,
      },
    ],
  },
};

custom-icon.vue

<script setup lang="ts">
import { h } from 'vue';
import { customIcons } from './custom-icons';

const props = defineProps<{
  name: string;
  size?: number | string;
  color?: string;
}>();

const render = () => {
  const icon = customIcons[props.name];
  if (!icon) return null;

  return h(
    'svg',
    {
      width: props.size || icon.width,
      height: props.size || icon.height,
      viewBox: `0 0 ${icon.width} ${icon.height}`,
      fill: 'none',
      xmlns: 'http://www.w3.org/2000/svg',
    },
    icon.paths.map((path, i) =>
      h('path', {
        key: i,
        d: path.d,
        fill: path.fill || props.color,
        stroke: path.stroke || props.color,
        'stroke-width': path['stroke-width'],
        'stroke-linecap': path['stroke-linecap'],
        'stroke-linejoin': path['stroke-linejoin'],
      }),
    ),
  );
};
</script>

<template>
  <render />
</template>

select-icon.vue

import { customIcons } from './custom-icons';

const mergedIcons = [
  ...icons,
  {
    name: 'Social',
    icons: socialIcons,
  },
  {
    name: 'Custom',
    icons: Object.keys(customIcons),
  },
];

Preview