Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Dynamic SVG Loading in Vue 3 with TypeScript and Vite

Tech May 15 1

Processing Country Data and Loading Dynamic SVGs

In this implementation, we'll demonstrate how to process API data containing country information and dynamically load corresponding SVG flags using Vue 3, TypeScript, and Vite.

Processing API Response Data

First, we need to process the raw data from our API to extract relevant information and prepare it for rendering:

for (let index = 0; index < apiData.value!.length; index++) {
  if (apiData.value !== undefined && apiData.value) {
    const responseContent: any = apiData.value[index].flagData;
    const htmlTagPosition = responseContent.indexOf('<');
    let textBeforeHTML: any;
    
    if (htmlTagPosition !== -1) {
      textBeforeHTML = responseContent.substring(0, htmlTagPosition);
      apiData.value[index].flagData = textBeforeHTML;
    }
  }

  const countryCode = apiData.value[index].nationCode;
  console.log(countryCode);

  if (countryCode) {
    const matchedNation = allNations.find((nation) => nation.code === countryCode);

    if (matchedNation) {
      // Add the SVG file path to our data object
      apiData.value[index].flagPath = matchedNation.svgPath;
      console.log('Matched nation SVG:', matchedNation.svgPath);
    } else {
      console.log('No matching nation found for:', countryCode);
    }
  }

  const currentItem = apiData.value[index];
  const processedItem = { _score: apiData.value[index] };
  displayList.value.push(processedItem);
  console.log(displayList.value);
}

The allNations is a JSON file containing country information with their corresponding SVG file paths. We match the API data with this JSON to get the appropriate SVG path.

Dynamic SVG Component

Here's how to implement a component that dynamically loads SVG images based on the processed data:

<template>
  <img :src="flagImageSrc" />
</template>

<script setup lang="ts">
import { ref, watchEffect } from 'vue';

const flagImageSrc = ref('');

watchEffect(() => {
  for (const item of displayList.value) {
    if (item._score && item._score.flagPath) { // Check if _score and flagPath exist
      loadFlagImage(item._score.flagPath);
    }
  }
});

async function loadFlagImage(path: string) {
  try {
    const imageModule = await import(`/@/assets/flags/${path}.svg`);
    flagImageSrc.value = imageModule.default;
  } catch (error) {
    console.error(`Failed to import SVG file for ${path}:`, error);
    // Fallback to default image if import fails
    flagImageSrc.value = require('/@/assets/flags/default.svg');
  }
}
</script>

Implementation in Other Components

When receiving data in other components, first check if the SVG path exists before attempting to render:

async function renderDynamicFlag(flagPath: string | undefined) {
  if (!flagPath) {
    console.log('No flag path provided');
    return;
  }
  
  try {
    const imageModule = await import(`/@/assets/flags/${flagPath}.svg`);
    return imageModule.default;
  } catch (error) {
    console.error(`Failed to load flag for ${flagPath}:`, error);
    return require('/@/assets/flags/default.svg');
  }
}

This approach ensures that only valid SVG paths are processed, providing a fallback mechanism when resources are unavailable.

Optimizing with Vite

Vite's native support for dynamic imports makes this implementation efficient. When you use import() with a static path, Vite will automatically code-split and bundle these assets separately.

For optimal performance, consider implementing a caching mechanism to avoid repeated imports of the same SVG files:

const svgCache = new Map();

async function getSvgWithCache(path: string) {
  if (svgCache.has(path)) {
    return svgCache.get(path);
  }
  
  try {
    const imageModule = await import(`/@/assets/flags/${path}.svg`);
    svgCache.set(path, imageModule.default);
    return imageModule.default;
  } catch (error) {
    console.error(`Failed to load SVG for ${path}:`, error);
    return require('/@/assets/flags/default.svg');
  }
}

This implementation demonstrates how to efficiently load dynamic SVG resources in a Vue 3 application with TypeScript and Vite, handling various edge cases while maintaining good performance.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.