From bbd7151480ad775f705033625973b8ffdfdd2c23 Mon Sep 17 00:00:00 2001
From: userquin <userquin@gmail.com>
Date: Tue, 3 Feb 2026 20:47:28 +0100
Subject: [PATCH 1/2] feat(i18n, ui): add search page title and description

---
 app/pages/search.vue      | 12 ++++++++++--
 i18n/locales/en.json      |  4 ++++
 i18n/locales/es.json      |  4 ++++
 lunaria/files/en-GB.json  |  4 ++++
 lunaria/files/en-US.json  |  4 ++++
 lunaria/files/es-419.json |  4 ++++
 lunaria/files/es-ES.json  |  4 ++++
 7 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/app/pages/search.vue b/app/pages/search.vue
index def113f99a..776ceb489a 100644
--- a/app/pages/search.vue
+++ b/app/pages/search.vue
@@ -581,12 +581,20 @@ function handleResultsKeydown(e: KeyboardEvent) {
 onKeyDown(['ArrowDown', 'ArrowUp', 'Enter'], handleResultsKeydown)
 
 useSeoMeta({
-  title: () => (query.value ? `Search: ${query.value} - npmx` : 'Search Packages - npmx'),
+  title: () =>
+    `${query.value ? $t('search.title_search', { search: query.value }) : $t('search.title_packages')} - npmx`,
+  description: () =>
+    query.value
+      ? $t('search.meta_description', { search: query.value })
+      : $t('search.meta_description_packages'),
 })
 
 defineOgImageComponent('Default', {
   title: 'npmx',
-  description: () => (query.value ? `Search results for "${query.value}"` : 'Search npm packages'),
+  description: () =>
+    query.value
+      ? $t('search.meta_description', { search: query.value })
+      : $t('search.meta_description_packages'),
   primaryColor: '#60a5fa',
 })
 </script>
diff --git a/i18n/locales/en.json b/i18n/locales/en.json
index 275bc81a1c..f6712fd8e6 100644
--- a/i18n/locales/en.json
+++ b/i18n/locales/en.json
@@ -28,6 +28,10 @@
     "updating": "(updating...)",
     "no_results": "No packages found for \"{query}\"",
     "title": "search",
+    "title_search": "search: {search}",
+    "title_packages": "search packages",
+    "meta_description": "Search results for '{search}'",
+    "meta_description_packages": "Search npm packages",
     "not_taken": "{name} is not taken",
     "claim_prompt": "Claim this package name on npm",
     "claim_button": "Claim \"{name}\"",
diff --git a/i18n/locales/es.json b/i18n/locales/es.json
index ef63753c4e..86910d834d 100644
--- a/i18n/locales/es.json
+++ b/i18n/locales/es.json
@@ -28,6 +28,10 @@
     "updating": "(actualizando...)",
     "no_results": "No se encontraron paquetes para \"{query}\"",
     "title": "búsqueda",
+    "title_search": "búsqueda: {search}",
+    "title_packages": "búsqueda de paquetes",
+    "meta_description": "Resultado de la búsqueda para '{search}'",
+    "meta_description_packages": "Búsqueda de paquetes npm",
     "not_taken": "{name} no está ocupado",
     "claim_prompt": "Reclamar este nombre de paquete en npm",
     "claim_button": "Reclamar \"{name}\"",
diff --git a/lunaria/files/en-GB.json b/lunaria/files/en-GB.json
index 3df010fb68..fee71b9c99 100644
--- a/lunaria/files/en-GB.json
+++ b/lunaria/files/en-GB.json
@@ -28,6 +28,10 @@
     "updating": "(updating...)",
     "no_results": "No packages found for \"{query}\"",
     "title": "search",
+    "title_search": "search: {search}",
+    "title_packages": "search packages",
+    "meta_description": "Search results for '{search}'",
+    "meta_description_packages": "Search npm packages",
     "not_taken": "{name} is not taken",
     "claim_prompt": "Claim this package name on npm",
     "claim_button": "Claim \"{name}\"",
diff --git a/lunaria/files/en-US.json b/lunaria/files/en-US.json
index 275bc81a1c..f6712fd8e6 100644
--- a/lunaria/files/en-US.json
+++ b/lunaria/files/en-US.json
@@ -28,6 +28,10 @@
     "updating": "(updating...)",
     "no_results": "No packages found for \"{query}\"",
     "title": "search",
+    "title_search": "search: {search}",
+    "title_packages": "search packages",
+    "meta_description": "Search results for '{search}'",
+    "meta_description_packages": "Search npm packages",
     "not_taken": "{name} is not taken",
     "claim_prompt": "Claim this package name on npm",
     "claim_button": "Claim \"{name}\"",
diff --git a/lunaria/files/es-419.json b/lunaria/files/es-419.json
index 380e47d975..8930546b4e 100644
--- a/lunaria/files/es-419.json
+++ b/lunaria/files/es-419.json
@@ -28,6 +28,10 @@
     "updating": "(actualizando...)",
     "no_results": "No se encontraron paquetes para \"{query}\"",
     "title": "búsqueda",
+    "title_search": "búsqueda: {search}",
+    "title_packages": "búsqueda de paquetes",
+    "meta_description": "Resultado de la búsqueda para '{search}'",
+    "meta_description_packages": "Búsqueda de paquetes npm",
     "not_taken": "{name} no está ocupado",
     "claim_prompt": "Reclamar este nombre de paquete en npm",
     "claim_button": "Reclamar \"{name}\"",
diff --git a/lunaria/files/es-ES.json b/lunaria/files/es-ES.json
index ef63753c4e..86910d834d 100644
--- a/lunaria/files/es-ES.json
+++ b/lunaria/files/es-ES.json
@@ -28,6 +28,10 @@
     "updating": "(actualizando...)",
     "no_results": "No se encontraron paquetes para \"{query}\"",
     "title": "búsqueda",
+    "title_search": "búsqueda: {search}",
+    "title_packages": "búsqueda de paquetes",
+    "meta_description": "Resultado de la búsqueda para '{search}'",
+    "meta_description_packages": "Búsqueda de paquetes npm",
     "not_taken": "{name} no está ocupado",
     "claim_prompt": "Reclamar este nombre de paquete en npm",
     "claim_button": "Reclamar \"{name}\"",

From 1aa65f68580d395f13095377a9552b1a4868f5da Mon Sep 17 00:00:00 2001
From: userquin <userquin@gmail.com>
Date: Tue, 3 Feb 2026 21:03:23 +0100
Subject: [PATCH 2/2] chore: use same title at `defineOgImageComponent `

---
 app/pages/search.vue | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/app/pages/search.vue b/app/pages/search.vue
index 776ceb489a..d01e0d9dbf 100644
--- a/app/pages/search.vue
+++ b/app/pages/search.vue
@@ -590,7 +590,8 @@ useSeoMeta({
 })
 
 defineOgImageComponent('Default', {
-  title: 'npmx',
+  title: () =>
+    `${query.value ? $t('search.title_search', { search: query.value }) : $t('search.title_packages')} - npmx`,
   description: () =>
     query.value
       ? $t('search.meta_description', { search: query.value })
