Back to blog
astro svelte react i18n typescript

Problems I Solved Building a Portfolio with Astro, Svelte, and React

Real challenges I faced building a multi-framework portfolio: Astro setup, i18n routing, Svelte + React integration, and Vercel deployment. How I solved each one.

· 8 min read
Markus Spiske photo

Problems?

A few months ago, I heard about Astro and its ability to mix different technologies within a single project. That inspired me to use React and Svelte simultaneously to showcase my skills in my portfolio. However, not everything was as simple as it seemed.

Lack of Knowledge in Astro

One of the first problems I faced was my limited knowledge of Astro, so I had to learn on the go. Fortunately, Astro is quite easy to pick up, and its documentation is very comprehensive.

The Installation Process

While setting up any project in any technology can be tedious, Astro simplifies installations with super simple commands.

In the end, I was left with a very clean and organized configuration file, along with other necessary configuration files like svelte.config.js. Here is my astro.config.mjs file:

import { defineConfig } from "astro/config";
import mdx from "@astrojs/mdx";
import react from "@astrojs/react";
import svelte from "@astrojs/svelte";
import tailwind from "@astrojs/tailwind";
import vercel from "@astrojs/vercel/serverless";

export default defineConfig({
  integrations: [react(), svelte(), tailwind(), mdx()],
  output: "server",
  adapter: vercel(),
  i18n: {
    defaultLocale: "en",
    locales: ["en", "es"],
    routing: {
      prefixDefaultLocale: true,
    },
  },
});

Astro even includes an adapter for Vercel, which is what I'm currently using. It was as easy as running a command to get my project ready and compatible with Vercel.

Integrating i18n with Astro

Astro offers a friendly integration with i18n, but I encountered a small obstacle: I completely forgot that my project was in server mode. This made fetching data for each language in both Svelte and React nearly impossible.

The issue arose because in both Svelte and React, I needed to get the URL, and one might think that simply pointing to window.location.href would suffice, but it does not. The solution was quite simple: using useEffect in React and onMount in Svelte to fetch the URL when the component loads.

So, I ended up with two hooks — one for React and one for Svelte:

// usei18n.ts (React)
export const useI18n = (route?: TranslateArgs) => {
  const [i18text, setI18text] = useState<string>("");
  const [lang, setLang] = useState<string>("en");

  useEffect(() => {
    const currentURL = new URL(window.location.href);
    const language = getLangFromUrl(currentURL);
    setLang(language);
    if (!route) return;
    const t = useTranslations(language as TranslationsArgs);
    setI18text(t(route as TranslateArgs));
  }, [route]);

  if (!route) return [lang];
  return [i18text, lang];
};
// usei18nSvelte.ts (Svelte)
export function useI18n(route?: TranslateArgs) {
  const currentURL = new URL(window.location.href);
  const lang = getLangFromUrl(currentURL);
  if (!route) return [lang];
  const t = useTranslations(lang as TranslationsArgs);
  return [t(route as TranslateArgs), lang];
}

Conclusions

Overall, Astro is a powerful and user-friendly tool that allows us to mix technologies and maintain a clean and organized project.

However, proficiency in various technologies is obviously very independent, but if you have the necessary knowledge, Astro is a tool that will enable you to do incredible things.