Repository: directus/directus
File: app/src/views/private/components/license-banner.vue (Vue)

Code before:
<script setup lang="ts">
import { useI18n } from 'vue-i18n';
import { useSettingsStore } from '@/stores/settings';
import { useServerStore } from '@/stores/server';
import { storeToRefs } from 'pinia';
import BannerSVG from '../../../assets/directus-bsl-banner.svg?raw';

const { t } = useI18n();

const settingsStore = useSettingsStore();

async function acceptTerms() {
	await settingsStore.updateSettings({ license_banner_seen: true });
	settingsStore.hydrate();
}

const { info } = storeToRefs(useServerStore());
</script>

<template>
	<v-dialog>
		<v-card>
			<div class="inner">
				<!-- eslint-disable-next-line vue/no-v-html -->
				<div class="banner-svg" v-html="BannerSVG"></div>

				<div class="left">
					<div class="message-copy">
						<v-card-title>{{ t('bsl_banner.welcome_to_directus') }}</v-card-title>
						<p>{{ t('bsl_banner.directus_free_use', { nbsp: '&nbsp;' }) }}</p>
						<p>{{ t('bsl_banner.organization_threshold') }}</p>
						<p>
							{{ t('bsl_banner.license_agreement') }}
							<a
								:href="`https://directus.io/bsl?utm_source=self_hosted&utm_medium=product&utm_campaign=2025_06_license_banner&utm_term=${info.version}&utm_content=bsl_1.1_link`"
								target="_blank"
							>
								{{ t('bsl_banner.directus_bsl') }}
							</a>
							{{ t('bsl_banner.and') }}
							<a
								:href="`https://directus.io/privacy?utm_source=self_hosted&utm_medium=product&utm_campaign=2025_06_license_banner&utm_term=${info.version}&utm_content=privacy_link`"
								target="_blank"
							>
								{{ t('bsl_banner.privacy_policy') }}
							</a>
						</p>
					</div>

					<v-card-actions>

Review comment (suggestion):
To be inline with other parts of the codebase[^1][^2][^3] we should use an `img` tag to render the svg. This would remove the need for `v-html`


[^1]: https://github.com/directus/directus/blob/main/app/src/views/public/public-view.vue#L65
[^2]: https://github.com/directus/directus/blob/main/app/src/displays/user/user.vue#L39
[^3]: https://github.com/directus/directus/blob/bc60657fc33587a0961164fc3d7ddffcd274c789/app/src/views/shared/shared-view.vue#L43


Code after:
<script setup lang="ts">
import { useI18n } from 'vue-i18n';
import { useSettingsStore } from '@/stores/settings';
import { useServerStore } from '@/stores/server';
import { storeToRefs } from 'pinia';
import BannerSVG from '../../../assets/directus-bsl-banner.svg?raw';

const { t } = useI18n();

const settingsStore = useSettingsStore();

async function acceptTerms() {
	await settingsStore.updateSettings({ accepted_terms: true });
	settingsStore.hydrate();
}

const { info } = storeToRefs(useServerStore());
</script>

<template>
	<v-dialog>
		<v-card>
			<div class="inner">
				<!-- eslint-disable-next-line vue/no-v-html -->
				<div class="banner-svg" v-html="BannerSVG"></div>

				<div class="left">
					<div class="message-copy">
						<v-card-title>{{ t('bsl_banner.welcome_to_directus') }}</v-card-title>
						<p>{{ t('bsl_banner.directus_free_use') }}</p>
						<p>{{ t('bsl_banner.organization_threshold') }}</p>
						<i18n-t keypath="bsl_banner.license_agreement" tag="p">
							<template #directusBsl>
								<a
									:href="`https://directus.io/bsl?utm_source=self_hosted&utm_medium=product&utm_campaign=2025_06_license_banner&utm_term=${info.version}&utm_content=bsl_1.1_link`"
								>
									{{ t('bsl_banner.directus_bsl') }}
								</a>
							</template>
							<template #privacyPolicy>
								<a
									:href="`https://directus.io/privacy?utm_source=self_hosted&utm_medium=product&utm_campaign=2025_06_license_banner&utm_term=${info.version}&utm_content=privacy_link`"
								>
									{{ t('bsl_banner.privacy_policy') }}
								</a>
							</template>
						</i18n-t>
					</div>

					<v-card-actions>