From 3c6db9b8f07db8943ae66e0a639ffeffa67196be Mon Sep 17 00:00:00 2001 From: Rijk van Zanten Date: Thu, 21 May 2020 18:16:12 -0400 Subject: [PATCH] Dynamic favicon (#607) * Fix favicon path in dev mode * Add favicon that matches project brand color --- public/index.html | 4 ++-- src/app.vue | 3 +++ src/utils/set-favicon/index.ts | 4 ++++ src/utils/set-favicon/set-favicon.ts | 29 ++++++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 src/utils/set-favicon/index.ts create mode 100644 src/utils/set-favicon/set-favicon.ts diff --git a/public/index.html b/public/index.html index afdd7f8093..4728f2a379 100644 --- a/public/index.html +++ b/public/index.html @@ -4,8 +4,8 @@ - - + + Directus diff --git a/src/app.vue b/src/app.vue index d498527228..6c344cf4d7 100644 --- a/src/app.vue +++ b/src/app.vue @@ -17,6 +17,7 @@ import { useAppStore } from '@/stores/app'; import { useUserStore } from '@/stores/user'; import { useProjectsStore } from '@/stores/projects'; import useWindowSize from '@/composables/use-window-size'; +import setFavicon from '@/utils/set-favicon'; export default defineComponent({ setup() { @@ -32,6 +33,8 @@ export default defineComponent({ }; }); + watch(() => projectsStore.currentProject.value?.color, setFavicon); + const { width } = useWindowSize(); watch(width, (newWidth, oldWidth) => { diff --git a/src/utils/set-favicon/index.ts b/src/utils/set-favicon/index.ts new file mode 100644 index 0000000000..90b82a05f3 --- /dev/null +++ b/src/utils/set-favicon/index.ts @@ -0,0 +1,4 @@ +import setFavicon from './set-favicon'; + +export { setFavicon }; +export default setFavicon; diff --git a/src/utils/set-favicon/set-favicon.ts b/src/utils/set-favicon/set-favicon.ts new file mode 100644 index 0000000000..aca24c34dc --- /dev/null +++ b/src/utils/set-favicon/set-favicon.ts @@ -0,0 +1,29 @@ +const svg = (color: string) => ` + + + + + +`; + +export default function setFavicon(color = '#2f80ed') { + const icon = svg(color); + const wrapper = document.createElement('div'); + wrapper.innerHTML = icon.trim(); + + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const iconSerialized = new XMLSerializer().serializeToString(wrapper.firstChild!); + + const string = 'data:image/svg+xml;base64,' + window.btoa(iconSerialized); + + const link: HTMLLinkElement = + document.querySelector("link[rel*='icon']") || document.createElement('link'); + link.type = 'image/x-icon'; + link.rel = 'icon'; + link.href = string; + document.getElementsByTagName('head')[0].appendChild(link); +}