diff --git a/src/components/BeeswarmChart.vue b/src/components/BeeswarmChart.vue
index 96ac51d71d71374c7eca7c604d5f7dd77fc4bb50..682eb1db802c3865a74c80e42a7640bad86ed67f 100644
--- a/src/components/BeeswarmChart.vue
+++ b/src/components/BeeswarmChart.vue
@@ -1,73 +1,75 @@
 <template>
   <section id="beeswarm">
     <div id="text1" class="text-container">
-    <p v-html="t('text.components.chartText.bubbleCheckbox')"></p>
-    <!-- Render the translated labels within the span elements -->
-    <p>
-      <span 
-        :class="['highlight', 'Demographiccharacteristics', { checked: isChecked.Demographiccharacteristics }]" 
-        @click="toggleCategory('Demographiccharacteristics')"
-      >
-        {{ t('text.components.chartText.bubbleLabels.Demographiccharacteristics') }}
-      </span>,
-      <span 
-        :class="['highlight', 'Health', { checked: isChecked.Health }]" 
-        @click="toggleCategory('Health')"
-      >
-        {{ t('text.components.chartText.bubbleLabels.Health') }}
-      </span>, 
-      <span 
-        :class="['highlight', 'Livingconditions', { checked: isChecked.Livingconditions }]" 
-        @click="toggleCategory('Livingconditions')"
-      >
-        {{ t('text.components.chartText.bubbleLabels.Livingconditions') }}
-      </span>, 
-      <span 
-        :class="['highlight', 'Socioeconomicstatus', { checked: isChecked.Socioeconomicstatus }]" 
-        @click="toggleCategory('Socioeconomicstatus')"
-      >
-        {{ t('text.components.chartText.bubbleLabels.Socioeconomicstatus') }}
-      </span>,
-      <span 
-        :class="['highlight', 'Riskperception', { checked: isChecked.Riskperception }]" 
-        @click="toggleCategory('Riskperception')"
-      >
-        {{ t('text.components.chartText.bubbleLabels.Riskperception') }}
-      </span>,
-      <span 
-        :class="['highlight', 'Landtenure', { checked: isChecked.Landtenure }]" 
-        @click="toggleCategory('Landtenure')"
-      >
-        {{ t('text.components.chartText.bubbleLabels.Landtenure') }}
-      </span>, & 
-      <span 
-        :class="['highlight', 'Exposure', { checked: isChecked.Exposure }]" 
-        @click="toggleCategory('Exposure')"
-      >
-        {{ t('text.components.chartText.bubbleLabels.Exposure') }} 
-      </span>
-      &nbsp;
-      <span v-html="t('text.components.chartText.bubbleCheckboxEnd')" />
-    </p>
-  </div>
-    <div id="text2" class="text-container tooltip-width">
-      <div id="tooltip" class="tooltip"><p v-html="t('text.components.chartText.bubbleText')"></p></div>
-      <em><p v-html="t('text.components.chartText.bubbleLegend')"></p></em>
+      <p v-html="bubbleCheckboxText"></p>
+      <!-- Render the translated labels within the span elements -->
+      <p>
+        <span 
+          :class="['highlight', 'Demographiccharacteristics', { checked: isChecked.Demographiccharacteristics }]" 
+          @click="toggleCategory('Demographiccharacteristics')"
+        >
+          {{ demographicText }}
+        </span>,
+        <span 
+          :class="['highlight', 'Health', { checked: isChecked.Health }]" 
+          @click="toggleCategory('Health')"
+        >
+          {{ healthText }}
+        </span>, 
+        <span 
+          :class="['highlight', 'Livingconditions', { checked: isChecked.Livingconditions }]" 
+          @click="toggleCategory('Livingconditions')"
+        >
+          {{ livingConditionsText }}
+        </span>, 
+        <span 
+          :class="['highlight', 'Socioeconomicstatus', { checked: isChecked.Socioeconomicstatus }]" 
+          @click="toggleCategory('Socioeconomicstatus')"
+        >
+          {{ socioeconomicStatusText }}
+        </span>,
+        <span 
+          :class="['highlight', 'Riskperception', { checked: isChecked.Riskperception }]" 
+          @click="toggleCategory('Riskperception')"
+        >
+          {{ riskPerceptionText }}
+        </span>,
+        <span 
+          :class="['highlight', 'Landtenure', { checked: isChecked.Landtenure }]" 
+          @click="toggleCategory('Landtenure')"
+        >
+          {{ landTenureText }}
+        </span>, & 
+        <span 
+          :class="['highlight', 'Exposure', { checked: isChecked.Exposure }]" 
+          @click="toggleCategory('Exposure')"
+        >
+          {{ exposureText }} 
+        </span>
+        &nbsp;
+        <span v-html="bubbleCheckboxEndText" />
+      </p>
     </div>
-    <div id="beeswarm-chart-container">
+    <div id="text2" class="text-container tooltip-width">
+      <div id="tooltip" class="tooltip">
+        <p v-html="bubbleTooltipText"></p>
+      </div>
+      <em><p v-html="bubbleLegendText"></p></em>
     </div>
+    <div id="beeswarm-chart-container"></div>
     <div id="text2" class="text-container tooltip-width">
-      <em><p v-html="t('text.components.chartText.bubbleYaxis')"></p></em>
+      <em><p v-html="bubbleYAxisText"></p></em>
     </div>
   </section>
 </template>
 
+
 <script setup>
-import { onMounted, ref } from "vue";
+import { ref, computed, onMounted } from "vue";
 import * as d3 from 'd3';
 import { useI18n } from 'vue-i18n';
 
-const { t } = useI18n();
+const { t, locale } = useI18n();
 const userLang = navigator.language || navigator.userLanguage;
 const isSpanish = userLang.startsWith('es');
 
@@ -101,6 +103,35 @@ const dimensionColors = {
   Exposure: "#FFA600"
 };
 
+// Computed properties for translations
+const bubbleCheckboxText = computed(() => t('text.components.chartText.bubbleCheckbox'));
+const bubbleCheckboxEndText = computed(() => t('text.components.chartText.bubbleCheckboxEnd'));
+const bubbleTooltipText = computed(() => t('text.components.chartText.bubbleText'));
+const bubbleLegendText = computed(() => t('text.components.chartText.bubbleLegend'));
+const bubbleYAxisText = computed(() => t('text.components.chartText.bubbleYaxis'));
+
+// Labels for each category
+const demographicText = computed(() => t('text.components.chartText.bubbleLabels.Demographiccharacteristics'));
+const healthText = computed(() => t('text.components.chartText.bubbleLabels.Health'));
+const livingConditionsText = computed(() => t('text.components.chartText.bubbleLabels.Livingconditions'));
+const socioeconomicStatusText = computed(() => t('text.components.chartText.bubbleLabels.Socioeconomicstatus'));
+const riskPerceptionText = computed(() => t('text.components.chartText.bubbleLabels.Riskperception'));
+const landTenureText = computed(() => t('text.components.chartText.bubbleLabels.Landtenure'));
+const exposureText = computed(() => t('text.components.chartText.bubbleLabels.Exposure'));
+
+// Computed function for generating tooltip text
+const generateTooltipText = (dataPoint) => {
+  return computed(() => {
+    const translatedDeterminant = locale.value === 'es' ? dataPoint.determinant_es : dataPoint.determinant_wrapped;
+    const determinant = `<strong>${translatedDeterminant}</strong>`;
+    const count = dataPoint.evidence_val;
+    const studyLabel = dataPoint.evidence_val === 1 ? t('text.components.chartText.singleStudy') : t('text.components.chartText.multipleStudies');
+    const appeared = t('text.components.chartText.appeared');
+
+    return `${determinant} ${appeared} ${count} ${studyLabel}`;
+  });
+};
+
 const patternId = 'pattern-stripe';
 
 // bar chart patterning and fills
@@ -333,25 +364,9 @@ function handleMouseOver(event, d) {
 
     /// Select the tooltip element
   const tooltip = d3.select('#tooltip');
-  const tooltipTemplate = "{determinant} {appeared} {count} {studyLabel}" 
-
-  function getTranslatedDeterminant(d) {
-    return isSpanish ? d.determinant_es : d.determinant_wrapped;
-  }
-  const translatedDeterminant = getTranslatedDeterminant(d);
-
-  // Dynamic values
-  const determinant = `<strong>${translatedDeterminant}</strong>`;
-  const count = d.evidence_val;
-  const studyLabel = d.evidence_val === 1 ? t('text.components.chartText.singleStudy') : t('text.components.chartText.multipleStudies');
-  const appeared = t('text.components.chartText.appeared');
-
-  // Directly construct the tooltip text using a template literal
-  const tooltipText = tooltipTemplate
-    .replace('{determinant}', determinant)
-    .replace('{appeared}', appeared)
-    .replace('{count}', count)
-    .replace('{studyLabel}', studyLabel);
+  
+  // Generate the tooltip text using the computed property
+  const tooltipText = generateTooltipText(d).value;
 
   // Update the tooltip with the constructed text
   tooltip.html('')
diff --git a/src/components/InteractiveDendrogram.vue b/src/components/InteractiveDendrogram.vue
index dab70432f706f848b646d2bbec1a86328dde9233..5ef6741076a7d3cbbe1e064adf1b7a736aee0633 100644
--- a/src/components/InteractiveDendrogram.vue
+++ b/src/components/InteractiveDendrogram.vue
@@ -46,12 +46,12 @@
 </template>
 
 <script setup>
-import { onMounted, ref } from 'vue';
+import { computed, onMounted, ref, watch } from 'vue';
 import { isMobile } from 'mobile-device-detect';
 import * as d3 from 'd3';
 import { useI18n } from 'vue-i18n';
 
-const { t } = useI18n();
+const { t, locale } = useI18n();
 
 // global variables
 const publicPath = import.meta.env.BASE_URL;
@@ -85,7 +85,6 @@ let linkWidthScale, nodeRadiusScale;
 
 onMounted(() => {
   const userLang = navigator.language || navigator.userLanguage;
-  const isSpanish = userLang.startsWith('es'); // Check if the language is Spanish
 
   loadData().then(() => {
     if (data.value.length > 0) {
@@ -97,10 +96,10 @@ onMounted(() => {
         .domain([0, d3.max(data.value, d => d.evidence_val)])
         .range([2, 9]);
 
-      transformData(isSpanish)
+      transformData()
         .then((result) => {
           calculateTextSize();
-          createDendrogram(result, isSpanish);
+          createDendrogram(result);
         })
         .catch((error) => {
           console.error('Error transforming data:', error);
@@ -109,6 +108,8 @@ onMounted(() => {
   });
 })
 
+
+
 async function loadData() {
   try {
     const jsonData = await d3.json(publicPath + 'indicator_uncertainty.json');
@@ -130,8 +131,10 @@ function calculateTextSize() {
   }
 }
 
-function transformData(isSpanish) {
+async function transformData() {
   return new Promise((resolve) => {
+    const isSpanish = locale.value === 'es'; // Determine if the current locale is Spanish
+
     const nestedData = data.value.reduce((acc, item) => {
       const dimensionName = isSpanish ? item.dimension_es : item.dimension;
       let dimensionObj = acc.find((d) => d.name === dimensionName);
@@ -151,7 +154,7 @@ function transformData(isSpanish) {
       determinantObj.children.push({
         name: indicatorName,
         evidence_val: item.evidence_val,
-        level_agreement: item.level_agreement
+        level_agreement: item.level_agreement,
       });
 
       return acc;
@@ -167,7 +170,7 @@ function transformData(isSpanish) {
       return node.totalEvidence;
     };
 
-    nestedData.forEach(dimension => calculateTotalEvidence(dimension));
+    nestedData.forEach((dimension) => calculateTotalEvidence(dimension));
 
     const result = { name: ' ', children: nestedData };
     resolve(result);
@@ -175,8 +178,15 @@ function transformData(isSpanish) {
 }
 
 
+watch(() => locale.value, async () => {
+  // Clear the existing SVG before creating a new dendrogram
+  d3.select('#dendrogram-container').select('svg').remove();
+
+  const result = await transformData();
+  createDendrogram(result);
+});
 
-function createDendrogram(result, isSpanish) {
+function createDendrogram(result) {
   const width = 1000;
   const height = 800;
   const marginTop = 40;
@@ -237,7 +247,7 @@ root.descendants().forEach(d => {
     .attr('cursor', 'pointer')
     .attr('pointer-events', 'all');
 
-    function update(event, source) {
+  function update(event, source) {
   const duration = 1200;
   const nodes = root.descendants().reverse();
   const links = root.links().filter(link => link.source.depth !== 0);
@@ -327,8 +337,8 @@ root.descendants().forEach(d => {
   nodeEnter.append('circle')
     .filter(d => d.depth !== 1)
     .attr('r', d => getNodeRadius(d))
-    .attr('fill', d =>  getNodeColor(d, isSpanish))
-    .attr('stroke', d => getNodeColor(d, isSpanish))
+    .attr('fill', d =>  getNodeColor(d))
+    .attr('stroke', d => getNodeColor(d))
     .attr('stroke-width', 2);
 
   const wrapWidth = mobileView ? 300 : 300;
@@ -344,10 +354,10 @@ root.descendants().forEach(d => {
     })
     .attr('text-anchor', d => d.depth === 1 ? 'end' : 'start')
     .text(d => d.depth === 3 ? `${d.data.name} (${d.data.evidence_val})` : d.data.name)
-    .style('fill', d => getNodeColor(d, isSpanish));
+    .style('fill', d => getNodeColor(d));
 
     // function to add line break to dimension labels after 2nd word if spanish, after first word if english
-    function wrapAfterSecondWord(textSelection, isSpanish) {
+    function wrapAfterSecondWord(textSelection) {
       textSelection.each(function() {
         const textElement = d3.select(this);
         const text = textElement.text();  // Get the original text
@@ -356,7 +366,7 @@ root.descendants().forEach(d => {
         const words = text.split(/\s+/);
 
         // For English: Break after 1st word, for Spanish: Break after 2nd word
-        const breakAfter = isSpanish ? 2 : 1;
+        const breakAfter = locale.value === 'es' ? 2 : 1;
 
         // If there are more than 2 words, wrap after the second word
         if (words.length > breakAfter) {
@@ -374,11 +384,11 @@ root.descendants().forEach(d => {
             .attr('dy', '1.2em')
             .text(words.slice(breakAfter).join(' '));
         }
-    });
-  }
+      });
+    }
 
   textElements.filter(d => d.depth === 1)
-  .call(wrapAfterSecondWord, isSpanish)
+  .call(wrapAfterSecondWord)
     .clone(true).lower()
     .attr('stroke-linejoin', 'round')
     .attr('stroke-width', 3)
@@ -427,12 +437,12 @@ root.descendants().forEach(d => {
       return diagonal({ source: o, target: o });
     })
     .attr('stroke-width', getLinkWidth)
-    .attr('stroke',  d => getLinkColor(d, isSpanish));
+    .attr('stroke',  d => getLinkColor(d));
 
   link.merge(linkEnter).transition(transition)
     .attr('d', diagonal)
     .attr('stroke-width', getLinkWidth)
-    .attr('stroke', d => getLinkColor(d, isSpanish));
+    .attr('stroke', d => getLinkColor(d));
 
   link.exit().transition(transition).remove()
     .attr('d', () => {
@@ -491,42 +501,38 @@ function wrap(text, width) {
   });
 }
 
-function getNodeColor(d, isSpanish) {
-  // Choose the correct color map based on the language
-  const colorMap = isSpanish ? dimensionColors_es : dimensionColors;
+function getNodeColor(d) {
+  // Choose the correct color map based on the current locale
+  const colorMap = locale.value === 'es' ? dimensionColors_es : dimensionColors;
   
+  let normalizedDimension;
   if (d.depth === 1) {
-    const normalizedDimension = normalizeDimensionName(d.data.name);
-    return colorMap[normalizedDimension] || 'transaprent';  // Fallback to grey if not found
+    normalizedDimension = normalizeDimensionName(d.data.name);
   } else if (d.parent && d.parent.depth === 1) {
-    const normalizedDimension = normalizeDimensionName(d.parent.data.name);
-    return colorMap[normalizedDimension] || '#ccc';
+    normalizedDimension = normalizeDimensionName(d.parent.data.name);
   } else if (d.parent && d.parent.parent && d.parent.parent.depth === 1) {
-    const normalizedDimension = normalizeDimensionName(d.parent.parent.data.name);
-    return colorMap[normalizedDimension] || '#ccc';
-  } else {
-    return 'transparent';  // Fallback color
+    normalizedDimension = normalizeDimensionName(d.parent.parent.data.name);
   }
+
+  // Return the color from the map, defaulting to '#ccc' if not found
+  return colorMap[normalizedDimension] || '#ccc';
 }
 
-function getLinkColor(d, isSpanish) {
-  const colorMap = isSpanish ? dimensionColors_es : dimensionColors;
+function getLinkColor(d) {
+  const colorMap = locale.value === 'es' ? dimensionColors_es : dimensionColors;
 
+  let normalizedDimension;
   if (d.target.depth === 3) {
-    const normalizedDimension = normalizeDimensionName(d.target.parent.parent.data.name);
-    return colorMap[normalizedDimension] || '#ccc';
+    normalizedDimension = normalizeDimensionName(d.target.parent.parent.data.name);
   } else if (d.target.depth === 2) {
-    const normalizedDimension = normalizeDimensionName(d.target.parent.data.name);
-    return colorMap[normalizedDimension] || '#ccc';
+    normalizedDimension = normalizeDimensionName(d.target.parent.data.name);
   } else if (d.target.depth === 1) {
-    const normalizedDimension = normalizeDimensionName(d.target.data.name);
-    return colorMap[normalizedDimension] || '#ccc';
-  } else {
-    return 'red';  // Fallback color for other cases
+    normalizedDimension = normalizeDimensionName(d.target.data.name);
   }
-}
-
 
+  // Return the color from the map, defaulting to '#ccc' if not found
+  return colorMap[normalizedDimension] || '#ccc';
+}
 
 function getLinkWidth(d) {
   if (d.target.depth === 3) {
diff --git a/src/components/LanguageButton.vue b/src/components/LanguageButton.vue
index 50b493accf1ef427b55b766790c508fccd8c3912..87e8321de2bf1207233b88e43887ca8a52540efa 100644
--- a/src/components/LanguageButton.vue
+++ b/src/components/LanguageButton.vue
@@ -10,7 +10,7 @@
   
   
 <script setup>
-import { ref } from 'vue';
+import { ref, watch } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRouter, useRoute } from 'vue-router';
 
@@ -21,7 +21,7 @@ const route = useRoute();
 // Create a reactive variable to track the selected language
 const selectedLanguage = ref(locale.value);
 
-function handleLanguageChange(event) {
+function handleLanguageChange() {
     switchLanguage(selectedLanguage.value);
 }
 
@@ -38,6 +38,18 @@ function switchLanguage(lang) {
     });
   }
 }
+
+// Watch for changes in route language parameter to sync with selectedLanguage
+watch(
+  () => route.params.lang,
+  (newLang) => {
+    if (newLang && locale.value !== newLang) {
+      locale.value = newLang;
+      selectedLanguage.value = newLang;
+    }
+  },
+  { immediate: true }
+);
 </script>