diff --git a/astro.config.mjs b/astro.config.mjs
index 0758b46..6ba1f0d 100644
--- a/astro.config.mjs
+++ b/astro.config.mjs
@@ -7,10 +7,17 @@ import tailwind from "@astrojs/tailwind";
// https://astro.build/config
export default defineConfig({
integrations: [react(), tailwind()],
- output: "hybrid",
+ output: "server", //El output server es necesario para que i18n funcione, para mas info mirar la documentacion del mismo
adapter: cloudflare({
}),
image: {
domains: ["yellowumbrella.dev"],
+ },
+ i18n: {
+ locales: ["es", "en"],
+ defaultLocale: "es",
+ routing: {
+ prefixDefaultLocale: true
+ }
}
});
\ No newline at end of file
diff --git a/src/components/ContactForm.tsx b/src/components/ContactForm.tsx
index af28291..f05899a 100644
--- a/src/components/ContactForm.tsx
+++ b/src/components/ContactForm.tsx
@@ -4,6 +4,7 @@ import PhoneInput, { isValidPhoneNumber } from "react-phone-number-input";
import { Turnstile } from "@marsidev/react-turnstile";
import type { TurnstileInstance } from "@marsidev/react-turnstile";
import "react-phone-number-input/style.css";
+import { useTranslationsReact, getLangFromUrlReact } from '../i18n/react-utils';
type FormInputs = {
empresa: string;
@@ -13,8 +14,15 @@ type FormInputs = {
mensaje: string;
};
+interface ContactFormProps {
+ lang?: string;
+}
-export default function ContactForm() {
+export default function ContactForm({ lang }: ContactFormProps = {}) {
+ // Detectar idioma desde la URL del navegador si no se proporciona
+ const currentLang = lang || getLangFromUrlReact(window.location.pathname);
+ const t = useTranslationsReact(currentLang as 'es' | 'en');
+
const {
register,
handleSubmit,
@@ -42,7 +50,7 @@ export default function ContactForm() {
}
if (!token) {
- setStatus({ type: "error", message: "Por favor, completa el captcha antes de enviar" });
+ setStatus({ type: "error", message: t('contact.form.captcha.required') });
return;
}
@@ -65,7 +73,7 @@ export default function ContactForm() {
if (!res.ok) {
const text = await res.text();
- throw new Error(text || "Error al enviar el formulario");
+ throw new Error(text || t('contact.form.error'));
}
setStatus({ type: "success" });
@@ -75,7 +83,7 @@ export default function ContactForm() {
// Reset Turnstile widget using ref
turnstileRef.current?.reset();
} catch (err: unknown) {
- setStatus({ type: "error", message: (err instanceof Error ? err.message : String(err)) || "Error inesperado" });
+ setStatus({ type: "error", message: (err instanceof Error ? err.message : String(err)) || t('contact.form.error') });
}
};
@@ -89,72 +97,72 @@ export default function ContactForm() {
>
- Nombre de la empresa
+ {t('contact.form.company')}
{errors.empresa && (
-
Este campo es obligatorio
+
{t('contact.form.company.required')}
)}
- Nombre y apellidos
+ {t('contact.form.name')}
{errors.nombreCompleto && (
-
Introduce tu nombre completo
+
{t('contact.form.name.required')}
)}
- Cargo en la empresa (opcional)
+ {t('contact.form.position')}
- Email
+ {t('contact.form.email')}
{errors.email && (
-
Introduce un email válido
+
{t('contact.form.email.required')}
)}
-
Teléfono (opcional)
+
{t('contact.form.phone')}
{telefono && typeof telefono === "string" && !isValidPhoneNumber(telefono) && (
- El número puede no ser válido. Revisa el país y formato.
+ {t('contact.form.phone.invalid')}
)}
- Mensaje
+ {t('contact.form.message')}
@@ -188,7 +196,7 @@ export default function ContactForm() {
siteKey={siteKey}
options={{
theme: "dark",
- language: "es",
+ language: currentLang as "es" | "en",
}}
onSuccess={(token) => {
setTurnstileToken(token);
@@ -212,13 +220,13 @@ export default function ContactForm() {
className="relative inline-flex items-center justify-center w-32 h-16 p-[2px] mb-2 mr-4 overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-[#ffd300] to-[#773376] group-hover:from-[#ffd300] group-hover:to-[#773376] hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-[#773376] dark:focus:ring-[#773376]"
>
- {isSubmitting ? "Enviando..." : "Enviar"}
+ {isSubmitting ? t('contact.form.sending') : t('contact.form.send')}
{status.type === "success" && (
- ¡Gracias! Hemos recibido tu solicitud.
+ {t('contact.form.success')}
)}
{status.type === "error" && (
{status.message}
diff --git a/src/components/Head.astro b/src/components/Head.astro
index 3c342eb..4affd8c 100644
--- a/src/components/Head.astro
+++ b/src/components/Head.astro
@@ -1,42 +1,47 @@
---
import Umbrella from '../components/svg/Umbrella.astro'
+import { getLangFromUrl, useTranslations } from '../i18n/utils';
+import { getRelativeLocaleUrl } from 'astro:i18n';
+
+const lang = getLangFromUrl(Astro.url);
+const t = useTranslations(lang);
---
-
It's raining outside, take this
-
Yellow Umbrella
+
{t('home.subtitle')}
+
{t('home.title')}
-
+
- ¿Quiénes somos?
+ {t('home.nav.about')}
- Blog
+ {t('home.nav.blog')}
-
+
- Redes sociales
+ {t('home.nav.social')}
-
+
- Contacto
+ {t('home.nav.contact')}
diff --git a/src/components/LanguagePicker.astro b/src/components/LanguagePicker.astro
new file mode 100644
index 0000000..604cbfc
--- /dev/null
+++ b/src/components/LanguagePicker.astro
@@ -0,0 +1,57 @@
+---
+import { languages } from '../i18n/ui';
+import { getLangFromUrl, useTranslatedPath, getRouteFromUrl } from '../i18n/utils';
+import { getRelativeLocaleUrl } from 'astro:i18n';
+
+const lang = getLangFromUrl(Astro.url);
+const translatePath = useTranslatedPath(lang);
+
+// Obtener la ruta actual sin el prefijo del idioma
+const currentRoute = getRouteFromUrl(Astro.url) || '';
+---
+
+
+
+ {Object.entries(languages).map(([langCode, label]) => {
+ const translatedRoute = translatePath(`/${currentRoute}`, langCode);
+ return (
+
+ {label}
+
+ );
+ })}
+
+
+
+
diff --git a/src/components/Navigation.astro b/src/components/Navigation.astro
new file mode 100644
index 0000000..ef45348
--- /dev/null
+++ b/src/components/Navigation.astro
@@ -0,0 +1,50 @@
+---
+import { getLangFromUrl, useTranslations } from '../i18n/utils';
+import { getRelativeLocaleUrl } from 'astro:i18n';
+
+const lang = getLangFromUrl(Astro.url);
+const t = useTranslations(lang);
+
+const menuItems = [
+ {
+ path: '',
+ label: t('nav.home')
+ },
+ {
+ path: lang === 'es' ? 'sobre-nosotros' : 'about-us',
+ label: t('nav.about')
+ },
+ {
+ path: lang === 'es' ? 'contacto' : 'contact',
+ label: t('nav.contact')
+ },
+ {
+ path: lang === 'es' ? 'redes-sociales' : 'social-networks',
+ label: t('nav.social')
+ },
+];
+---
+
+
+
+
+
+
diff --git a/src/i18n/react-utils.ts b/src/i18n/react-utils.ts
new file mode 100644
index 0000000..4a84b81
--- /dev/null
+++ b/src/i18n/react-utils.ts
@@ -0,0 +1,13 @@
+import { ui, defaultLang } from './ui';
+
+export function useTranslationsReact(lang: keyof typeof ui) {
+ return function t(key: keyof typeof ui[typeof defaultLang]) {
+ return ui[lang][key] || ui[defaultLang][key];
+ }
+}
+
+export function getLangFromUrlReact(url: string) {
+ const [, lang] = url.split('/');
+ if (lang in ui) return lang as keyof typeof ui;
+ return defaultLang;
+}
diff --git a/src/i18n/ui.ts b/src/i18n/ui.ts
new file mode 100644
index 0000000..2a179b1
--- /dev/null
+++ b/src/i18n/ui.ts
@@ -0,0 +1,107 @@
+export const languages = {
+ es: 'Español',
+ en: 'English',
+};
+
+export const defaultLang = 'es';
+export const showDefaultLang = false;
+
+export const routes = {
+ en: {
+ 'sobre-nosotros': 'about-us',
+ 'contacto': 'contact',
+ 'redes-sociales': 'social-networks',
+ },
+ es: {
+ 'about-us': 'sobre-nosotros',
+ 'contact': 'contacto',
+ 'social-networks': 'redes-sociales',
+ },
+};
+
+export const ui = {
+ es: {
+ 'site.title': 'Yellow Umbrella',
+ 'site.description': 'The Yellow Umbrella Website ☂️',
+ 'nav.home': 'Inicio',
+ 'nav.about': 'Sobre nosotros',
+ 'nav.contact': 'Contacto',
+ 'nav.social': 'Redes sociales',
+ 'home.title': 'Yellow Umbrella',
+ 'home.subtitle': 'It\'s raining outside, take this',
+ 'home.nav.about': '¿Quiénes somos?',
+ 'home.nav.blog': 'Blog',
+ 'home.nav.social': 'Redes sociales',
+ 'home.nav.contact': 'Contacto',
+ 'about.title': 'Sobre nosotros',
+ 'about.description': 'Conoce quienes somos y cual es nuestra misión.',
+ 'contact.title': 'Contacto',
+ 'contact.description': 'Cuéntanos tu proyecto y te responderemos lo antes posible.',
+ 'contact.form.company': 'Nombre de la empresa',
+ 'contact.form.company.placeholder': 'Yellow Umbrella Tech',
+ 'contact.form.company.required': 'Este campo es obligatorio',
+ 'contact.form.name': 'Nombre y apellidos',
+ 'contact.form.name.placeholder': 'Perico Palotes Palez',
+ 'contact.form.name.required': 'Introduce tu nombre completo',
+ 'contact.form.position': 'Cargo en la empresa (opcional)',
+ 'contact.form.position.placeholder': 'CEO, CTO, etc.',
+ 'contact.form.email': 'Email',
+ 'contact.form.email.placeholder': 'ana.garcia@empresa.com',
+ 'contact.form.email.required': 'Introduce un email válido',
+ 'contact.form.phone': 'Teléfono (opcional)',
+ 'contact.form.phone.placeholder': '+34 600 123 456',
+ 'contact.form.phone.invalid': 'El número puede no ser válido. Revisa el país y formato.',
+ 'contact.form.message': 'Mensaje',
+ 'contact.form.message.placeholder': 'Cuéntanos en qué podemos ayudarte...',
+ 'contact.form.captcha.required': 'Por favor, completa el captcha antes de enviar',
+ 'contact.form.send': 'Enviar',
+ 'contact.form.sending': 'Enviando...',
+ 'contact.form.success': '¡Gracias! Hemos recibido tu solicitud.',
+ 'contact.form.error': 'Error al enviar el formulario',
+ 'social.title': 'Redes sociales',
+ 'social.description': 'Enlaces a nuestras redes sociales:',
+ 'language.switch': 'Cambiar idioma',
+ },
+ en: {
+ 'site.title': 'Yellow Umbrella',
+ 'site.description': 'The Yellow Umbrella Website ☂️',
+ 'nav.home': 'Home',
+ 'nav.about': 'About us',
+ 'nav.contact': 'Contact',
+ 'nav.social': 'Social networks',
+ 'home.title': 'Yellow Umbrella',
+ 'home.subtitle': 'It\'s raining outside, take this',
+ 'home.nav.about': 'About us',
+ 'home.nav.blog': 'Blog',
+ 'home.nav.social': 'Socials',
+ 'home.nav.contact': 'Contact',
+ 'about.title': 'About us',
+ 'about.description': 'Discover who we are and what is our mission.',
+ 'contact.title': 'Contact',
+ 'contact.description': 'Tell us about your project and we will contact you as soon as possible.',
+ 'contact.form.company': 'Company name',
+ 'contact.form.company.placeholder': 'Yellow Umbrella Tech',
+ 'contact.form.company.required': 'This field is required',
+ 'contact.form.name': 'Full name',
+ 'contact.form.name.placeholder': 'Jane Doe',
+ 'contact.form.name.required': 'Please enter your full name',
+ 'contact.form.position': 'Position in company (optional)',
+ 'contact.form.position.placeholder': 'CEO, CTO, etc.',
+ 'contact.form.email': 'Email',
+ 'contact.form.email.placeholder': 'jane.doe@company.com',
+ 'contact.form.email.required': 'Please enter a valid email',
+ 'contact.form.phone': 'Phone (optional)',
+ 'contact.form.phone.placeholder': '+1 555 123 456',
+ 'contact.form.phone.invalid': 'The number may not be valid. Check the country and format.',
+ 'contact.form.message': 'Message',
+ 'contact.form.message.placeholder': 'Tell us how we can help you...',
+ 'contact.form.captcha.required': 'Please complete the captcha before submitting',
+ 'contact.form.send': 'Send',
+ 'contact.form.sending': 'Sending...',
+ 'contact.form.success': 'Thank you! We have received your request.',
+ 'contact.form.error': 'Error sending the form',
+ 'social.title': 'Social networks',
+ 'social.description': 'Links to our social networks:',
+ 'language.switch': 'Change language',
+ },
+} as const;
diff --git a/src/i18n/utils.ts b/src/i18n/utils.ts
new file mode 100644
index 0000000..d357012
--- /dev/null
+++ b/src/i18n/utils.ts
@@ -0,0 +1,62 @@
+import { ui, defaultLang, routes } from './ui';
+
+export function getLangFromUrl(url: URL) {
+ const [, lang] = url.pathname.split('/');
+ if (lang in ui) return lang as keyof typeof ui;
+ return defaultLang;
+}
+
+export function useTranslations(lang: keyof typeof ui) {
+ return function t(key: keyof typeof ui[typeof defaultLang]) {
+ return ui[lang][key] || ui[defaultLang][key];
+ }
+}
+
+export function useTranslatedPath(lang: keyof typeof ui) {
+ return function translatePath(path: string, targetLang: string = lang) {
+ // Si es la página de inicio
+ if (!path || path === '/' || path === '') {
+ return `/${targetLang}/`;
+ }
+
+ // Remover el slash inicial si existe
+ const cleanPath = path.startsWith('/') ? path.substring(1) : path;
+
+ // Si el path está vacío después de limpiar, es página de inicio
+ if (!cleanPath) {
+ return `/${targetLang}/`;
+ }
+
+ // Verificar si necesita traducción de ruta
+ if (routes[targetLang] && routes[targetLang][cleanPath]) {
+ const translatedRoute = routes[targetLang][cleanPath];
+ return `/${targetLang}/${translatedRoute}`;
+ }
+
+ // Si no hay traducción, usar el path original
+ return `/${targetLang}/${cleanPath}`;
+ }
+}
+
+export function getRouteFromUrl(url: URL): string | undefined {
+ const pathname = url.pathname;
+ const parts = pathname.split('/').filter(Boolean); // Remover elementos vacíos
+
+ if (parts.length === 0) {
+ return ''; // página de inicio
+ }
+
+ // Si el primer elemento es un código de idioma, omítelo
+ const currentLang = getLangFromUrl(url);
+ if (parts[0] === currentLang) {
+ parts.shift(); // Remover el código de idioma
+ }
+
+ // Si no hay más partes, es la página de inicio
+ if (parts.length === 0) {
+ return '';
+ }
+
+ // Devolver la última parte como la ruta actual
+ return parts[parts.length - 1];
+}
diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro
index a1d9543..5a14200 100644
--- a/src/layouts/Layout.astro
+++ b/src/layouts/Layout.astro
@@ -7,12 +7,15 @@ const { title } = Astro.props;
import { ViewTransitions } from 'astro:transitions';
import { InteractiveRain } from "../components/Rain.jsx";
import { fade } from 'astro:transitions';
+import { getLangFromUrl, useTranslations } from '../i18n/utils';
+import LanguagePicker from '../components/LanguagePicker.astro';
-
+const lang = getLangFromUrl(Astro.url);
+const t = useTranslations(lang);
---
-
+
@@ -26,28 +29,29 @@ import { fade } from 'astro:transitions';
-
+
-
-
+
+
+
diff --git a/src/pages/contacto.astro b/src/pages/contacto.astro
deleted file mode 100644
index d017388..0000000
--- a/src/pages/contacto.astro
+++ /dev/null
@@ -1,21 +0,0 @@
----
-import Layout from "../layouts/Layout.astro";
-import ContactForm from "../components/ContactForm.tsx";
-import Head from "../components/Head.astro";
----
-
-
-
-
-
-
-
Contacto
-
- Cuéntanos tu proyecto y te responderemos lo antes posible.
-
-
-
-
-
-
-
diff --git a/src/pages/en/about-us.astro b/src/pages/en/about-us.astro
new file mode 100644
index 0000000..6fddb3c
--- /dev/null
+++ b/src/pages/en/about-us.astro
@@ -0,0 +1,32 @@
+---
+import Head from "../../components/Head.astro";
+import Layout from "../../layouts/Layout.astro";
+import { getLangFromUrl, useTranslations } from '../../i18n/utils';
+
+const lang = getLangFromUrl(Astro.url);
+const t = useTranslations(lang);
+---
+
+
+
+
+
+
{t('about.title')}
+
+
+
+ Yellow Umbrella means many things. For you, if you are the owner
+ of an emerging business, it means shelter and coverage for all your
+ cloud, cybersecurity, and development needs.
+
+ We are a small group dedicated to ensuring your company can grow peacefully in a world
+ increasingly dependent on good software.
+
+ Our values are clear: We are committed to
+ open source and accessibility to our services and projects. Our future together does not imply dependency.
+ We seek to cover you and train your team so that when the time comes, you can close the umbrella
+ and continue your path without us.
+
+
+
+
diff --git a/src/pages/en/contact.astro b/src/pages/en/contact.astro
new file mode 100644
index 0000000..35ae5cf
--- /dev/null
+++ b/src/pages/en/contact.astro
@@ -0,0 +1,24 @@
+---
+import Layout from "../../layouts/Layout.astro";
+import ContactForm from "../../components/ContactForm";
+import Head from "../../components/Head.astro";
+import { getLangFromUrl, useTranslations } from '../../i18n/utils';
+
+const lang = getLangFromUrl(Astro.url);
+const t = useTranslations(lang);
+---
+
+
+
+
+
+
+
{t('contact.title')}
+
+ {t('contact.description')}
+
+
+
+
+
+
diff --git a/src/pages/en/index.astro b/src/pages/en/index.astro
new file mode 100644
index 0000000..625eb51
--- /dev/null
+++ b/src/pages/en/index.astro
@@ -0,0 +1,16 @@
+---
+import Layout from "../../layouts/Layout.astro";
+import Head from "../../components/Head.astro";
+import { getLangFromUrl, useTranslations } from '../../i18n/utils';
+
+const lang = getLangFromUrl(Astro.url);
+const t = useTranslations(lang);
+---
+
+
+
+
+
diff --git a/src/pages/en/social-networks.astro b/src/pages/en/social-networks.astro
new file mode 100644
index 0000000..ff1a6fa
--- /dev/null
+++ b/src/pages/en/social-networks.astro
@@ -0,0 +1,45 @@
+---
+import Layout from "../../layouts/Layout.astro";
+import SocialCard from "../../components/SocialCard.astro";
+import Head from "../../components/Head.astro";
+import data from "../../api/socials.json";
+import twitter from "../../images/twitter.svg";
+import github from "../../images/github-circle.svg";
+import linkedin from "../../images/linkedin.svg";
+import { getLangFromUrl, useTranslations } from '../../i18n/utils';
+
+const lang = getLangFromUrl(Astro.url);
+const t = useTranslations(lang);
+
+// Crear mapeo de iconos
+const iconMap = {
+ "twitter": twitter,
+ "github-circle": github,
+ "linkedin": linkedin
+};
+
+export const prerender = false
+---
+
+
+
+
+
{t('social.title')}
+
+
+
{t('social.description')}
+
+
+ {
+ data.socials.map((output, index) => (
+
+ ))
+ }
+
+
+
diff --git a/src/pages/es/contacto.astro b/src/pages/es/contacto.astro
new file mode 100644
index 0000000..35ae5cf
--- /dev/null
+++ b/src/pages/es/contacto.astro
@@ -0,0 +1,24 @@
+---
+import Layout from "../../layouts/Layout.astro";
+import ContactForm from "../../components/ContactForm";
+import Head from "../../components/Head.astro";
+import { getLangFromUrl, useTranslations } from '../../i18n/utils';
+
+const lang = getLangFromUrl(Astro.url);
+const t = useTranslations(lang);
+---
+
+
+
+
+
+
+
{t('contact.title')}
+
+ {t('contact.description')}
+
+
+
+
+
+
diff --git a/src/pages/es/index.astro b/src/pages/es/index.astro
new file mode 100644
index 0000000..625eb51
--- /dev/null
+++ b/src/pages/es/index.astro
@@ -0,0 +1,16 @@
+---
+import Layout from "../../layouts/Layout.astro";
+import Head from "../../components/Head.astro";
+import { getLangFromUrl, useTranslations } from '../../i18n/utils';
+
+const lang = getLangFromUrl(Astro.url);
+const t = useTranslations(lang);
+---
+
+
+
+
+
diff --git a/src/pages/redes-sociales.astro b/src/pages/es/redes-sociales.astro
similarity index 52%
rename from src/pages/redes-sociales.astro
rename to src/pages/es/redes-sociales.astro
index 71a60ed..ff1a6fa 100644
--- a/src/pages/redes-sociales.astro
+++ b/src/pages/es/redes-sociales.astro
@@ -1,41 +1,45 @@
----
-import Layout from "../layouts/Layout.astro";
-import SocialCard from "../components/SocialCard.astro";
-import Head from "../components/Head.astro";
-import data from "../api/socials.json";
-import twitter from "../images/twitter.svg";
-import github from "../images/github-circle.svg";
-import linkedin from "../images/linkedin.svg";
-
-// Crear mapeo de iconos
-const iconMap = {
- "twitter": twitter,
- "github-circle": github,
- "linkedin": linkedin
-};
-
-export const prerender = false
----
-
-
-
-
-
Redes sociales
-
-
-
Enlaces a nuestras redes sociales:
-
-
- {
- data.socials.map((output, index) => (
-
- ))
- }
-
-
-
\ No newline at end of file
+---
+import Layout from "../../layouts/Layout.astro";
+import SocialCard from "../../components/SocialCard.astro";
+import Head from "../../components/Head.astro";
+import data from "../../api/socials.json";
+import twitter from "../../images/twitter.svg";
+import github from "../../images/github-circle.svg";
+import linkedin from "../../images/linkedin.svg";
+import { getLangFromUrl, useTranslations } from '../../i18n/utils';
+
+const lang = getLangFromUrl(Astro.url);
+const t = useTranslations(lang);
+
+// Crear mapeo de iconos
+const iconMap = {
+ "twitter": twitter,
+ "github-circle": github,
+ "linkedin": linkedin
+};
+
+export const prerender = false
+---
+
+
+
+
+
{t('social.title')}
+
+
+
{t('social.description')}
+
+
+ {
+ data.socials.map((output, index) => (
+
+ ))
+ }
+
+
+
diff --git a/src/pages/sobre-nosotros.astro b/src/pages/es/sobre-nosotros.astro
similarity index 74%
rename from src/pages/sobre-nosotros.astro
rename to src/pages/es/sobre-nosotros.astro
index 2dedf93..511a5bb 100644
--- a/src/pages/sobre-nosotros.astro
+++ b/src/pages/es/sobre-nosotros.astro
@@ -1,31 +1,32 @@
----
-
-import Head from "../components/Head.astro";
-import Layout from "../layouts/Layout.astro";
-
-
----
-
-
-
-
-
-
Sobre nosotros
-
-
-
- Yellow Umbrella significa muchas cosas. Para tí, si eres el dueño
- de un negocio emergente, significa resguardo y cobertura de todas tus necesidades
- de cloud, ciberseguridad, y desarrollo.
-
- Somos un pequeño grupo dedicado a que tu empresa pueda crecer tranquila en un mundo cada vez
- más dependiente de un buen software.
-
- Nuestros valores son claros: Estamos comprometidos con el
- código abierto y la accesibilidad a nuestros servicios y proyectos. Nuestro futuro juntos no implica dependencia.
- Buscamos cubrirte y entrenar a tu equipo para que llegado el momento, puedas cerrar el paragüas
- y continuar tu camino sin nosotros.
-
-
-
-
\ No newline at end of file
+---
+import Head from "../../components/Head.astro";
+import Layout from "../../layouts/Layout.astro";
+import { getLangFromUrl, useTranslations } from '../../i18n/utils';
+
+const lang = getLangFromUrl(Astro.url);
+const t = useTranslations(lang);
+---
+
+
+
+
+
+
{t('about.title')}
+
+
+
+ Yellow Umbrella significa muchas cosas. Para tí, si eres el dueño
+ de un negocio emergente, significa resguardo y cobertura de todas tus necesidades
+ de cloud, ciberseguridad, y desarrollo.
+
+ Somos un pequeño grupo dedicado a que tu empresa pueda crecer tranquila en un mundo cada vez
+ más dependiente de un buen software.
+
+ Nuestros valores son claros: Estamos comprometidos con el
+ código abierto y la accesibilidad a nuestros servicios y proyectos. Nuestro futuro juntos no implica dependencia.
+ Buscamos cubrirte y entrenar a tu equipo para que llegado el momento, puedas cerrar el paragüas
+ y continuar tu camino sin nosotros.
+
+
+
+
diff --git a/src/pages/index.astro b/src/pages/index.astro
index 9732403..39d3888 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -1,12 +1,5 @@
---
-import Layout from "../layouts/Layout.astro";
-import Head from "../components/Head.astro";
+//Esta pagina es necesaria para que i18n funcione.
+// Redirección automática al idioma predeterminado (español)
+return Astro.redirect('/es/');
---
-
-
-
-
-