<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Enmanuel Jarquín</title>
    <description>The latest articles on DEV Community by Enmanuel Jarquín (@theenmanuel23).</description>
    <link>https://dev.to/theenmanuel23</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F37009%2F9b5e54aa-f1e5-4222-8501-e87503e30112.png</url>
      <title>DEV Community: Enmanuel Jarquín</title>
      <link>https://dev.to/theenmanuel23</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/theenmanuel23"/>
    <language>en</language>
    <item>
      <title>What Technologies Should I Use in My Application?</title>
      <dc:creator>Enmanuel Jarquín</dc:creator>
      <pubDate>Sun, 16 Mar 2025 00:27:26 +0000</pubDate>
      <link>https://dev.to/theenmanuel23/what-technologies-should-i-use-in-my-application-39bl</link>
      <guid>https://dev.to/theenmanuel23/what-technologies-should-i-use-in-my-application-39bl</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/theenmanuel23/que-tecnologias-usar-en-mi-aplicacion-ahl"&gt;Spanish version&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One of the most challenging things at the start of a project is deciding which technologies to use.&lt;/strong&gt;&lt;br&gt;
For that reason, I want to share my experience, hoping it will be useful to others.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stack
&lt;/h2&gt;

&lt;p&gt;Here's the stack in case you don't want to read the full post or don't have much time.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Supabase&lt;/strong&gt;:
To manage my Postgres DB and avoid creating a backend server with APIs (CRUD), it has a client library that simplifies database interactions; it can be used from a server or a client app (browser, mobile devices, etc).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NextJS&lt;/strong&gt;:
Using the new versions of NextJS and now with the new ways to deal with routers and service side components made it much easier to build the app using ReactJS components that connect directly to the database with Supabase. For instance, use the native HTML method to send form actions. When I integrated it, I was really surprised at how fast the development was.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Turborepo&lt;/strong&gt;:
The setup was really simple. I had been using NX in enterprise projects, but I wanted to give it a chance. NX offers more options to configure, but in my case Turborepo was more than enough.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TailwindCSS&lt;/strong&gt;:
To be honest, I don't like CSS, and I didn't want to manually style everything. Since it is time-consuming, I opted for TailwindCSS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shadcn&lt;/strong&gt;:
One of the best decisions!. It combines reusable components with the flexibility of creating them from scratch. This tool generates the component in your code base, allowing you to customize it and it is fully compatible with TailwindCSS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clerk&lt;/strong&gt;:
To avoid building authentication from scratch. It manages users, provides different authentication methods, an account management panel, buttons, etc. You just configure the provider and that's it. However, it's price is 20$/month, while Supabase also supports authentication but requires more custom coding. So, depending on your budget, you could also use Supabase. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvxb1nxon3nwn4h75b76t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvxb1nxon3nwn4h75b76t.png" alt="Image description" width="416" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fycolyn485rbko31ojqvv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fycolyn485rbko31ojqvv.png" alt="Image description" width="725" height="670"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vercel&lt;/strong&gt;:
For setting up environments. It was so easy to associate my domain and configure subdomains with just a few clicks. If I had done it manually, I would have needed to configure HTTPS and set up certificates, wildcards, etc, to support subdomains.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Namecheap&lt;/strong&gt;:
I already have some experience configuring the basics of domains, subdomains, and emails with Google.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google&lt;/strong&gt;:
I configured Google services with Namecheap for emails. It's relatively cheap for starting out and having a professional email.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker&lt;/strong&gt;:
Not optional- &lt;strong&gt;required by Supabase&lt;/strong&gt; for local development.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;I wanted to try out new technologies.&lt;/li&gt;
&lt;li&gt;I wanted to build an MVP.&lt;/li&gt;
&lt;li&gt;"Suddenly" I found myself without a project, and now the idea of an MVP was not optional anymore- but I'll talk about that in another post.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Application
&lt;/h2&gt;

&lt;p&gt;The app is a web app. The initial idea was (or is) an app for &lt;strong&gt;digitizing restaurant menus&lt;/strong&gt;. Restaurants could configure their products, prices, and branches and associate products with specific locations. &lt;br&gt;
Initially, the idea was that consumers could place orders from the app, but that added a layer of complexity that would have delayed the MVP launch. So, that feature was moved to a second iteration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdwiqflglhz62h0253se0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdwiqflglhz62h0253se0.png" alt="Image description" width="800" height="465"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Backoffice for restaurants&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4lqmyf1fbghv3rp1yca0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4lqmyf1fbghv3rp1yca0.png" alt="Image description" width="432" height="952"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Menu app for consumers&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Decision criteria
&lt;/h2&gt;

&lt;p&gt;I wanted to &lt;strong&gt;speed up basic or repetitive tasks/processes&lt;/strong&gt; so I could focus on learning new things or areas I rarely work on in my regular job.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Everything revolved around the idea of the MVP, so I needed technologies that allowed me to iterate quickly.&lt;/li&gt;
&lt;li&gt;I wanted &lt;strong&gt;technologies that pushed me to improve&lt;/strong&gt; in areas I wasn't very familiar with, like &lt;strong&gt;real-time apps, monorepositories, Github Actions&lt;/strong&gt;, etc, while still leveraging technologies I already knew to avoid wasting time.&lt;/li&gt;
&lt;li&gt;I didn't want to waste time on repetitive setups like authentication, APIs (CRUDs), DB configurations, etc.&lt;/li&gt;
&lt;li&gt;The stack had to offer &lt;strong&gt;good performance by default&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I didn't want to spend time on CSS&lt;/strong&gt; and writing styles from scratch, nor did I want to build basic components like buttons, form fields, etc..&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;If someone asked me what technologies I would suggest for an MVP nowadays, I would highlight two: &lt;strong&gt;Supabase&lt;/strong&gt; and &lt;strong&gt;NestJS&lt;/strong&gt;; the rest could vary.&lt;/p&gt;

&lt;p&gt;🎥 &lt;strong&gt;Video Demo of the App&lt;/strong&gt;: &lt;a href="https://youtu.be/fyOKg2mjpTo" rel="noopener noreferrer"&gt;https://youtu.be/fyOKg2mjpTo&lt;/a&gt;&lt;br&gt;
🔗 &lt;strong&gt;Domain &amp;amp; Subdomain Setup with Namecheap and Vercel&lt;/strong&gt;:  &lt;a href="https://youtu.be/IY05UEV6DJY" rel="noopener noreferrer"&gt;https://youtu.be/IY05UEV6DJY&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Qué tecnologías usar en mi aplicación?</title>
      <dc:creator>Enmanuel Jarquín</dc:creator>
      <pubDate>Sat, 15 Mar 2025 19:31:05 +0000</pubDate>
      <link>https://dev.to/theenmanuel23/que-tecnologias-usar-en-mi-aplicacion-ahl</link>
      <guid>https://dev.to/theenmanuel23/que-tecnologias-usar-en-mi-aplicacion-ahl</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.to/theenmanuel23/what-technologies-should-i-use-in-my-application-39bl"&gt;English version&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Una de las cosas mas complicadas al inicio de un proyecto es decidir que tecnologías usar. Por tal motivo quiero compartir mi experiencia esperando sea de utilidad.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stack
&lt;/h2&gt;

&lt;p&gt;Aquí el stack en caso de que no quieras leer el post entero o no tienes mucho tiempo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Supabase&lt;/strong&gt;:
Para gestionar mi base de datos en postgres, me evita crear un backend para las APIs ya  que te un cliente el cual facilita la interación con la base de datos, puede usarse desde el server o desde app clientes que corren en el browser o móbiles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NextJS&lt;/strong&gt;:
Usando las nuevas versiones de NextJS y ahora con las nuevas formas de gestionar routers y server side components fue mucho mas sencillo crear una app usando componentes de ReactJS que se conectan a la DB directamente junto con supabase, por ejemplo usando la forma nativa de HTML para enviar los actions de un form, cuando lo hize realmente me soprendió lo rápido que es desarrollar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TurboRepo&lt;/strong&gt;:
La configuración es realmente sencilla, venia usando NX en proyectos empresariales y queria darle una oportunidad a esta otra herramienta,  consigues lo mismo que NX pero realmente es muy sencillo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tailwindcss&lt;/strong&gt;:
Para iniciar, no me gusta el CSS, y para enviar crear estilos por mi propia cuenta, me incliné por css.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shadcn&lt;/strong&gt;:
Esta fue una de las mejores decisiones, porque combina la parte de reutilizar componentes, y el crearlos desde cero, esta herramienta te genera el componente desde cero, permitiendote ver todo el código, aprender, y personalizar fácilmente y es totalmente compatible con tailwindcss.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clerk&lt;/strong&gt;:
Para evitar crear la pate de autenticación de cero, te permite gestionar los usuarios, brinda diferentes formas de autenticar, te proporciona una panel para gestion de cuenta, los botones, etc. Tu solo configuras el provider y listo, el problema es que su precio es de 20$ y Supabase ya te permite configurar la autenticación pero tienes que escribir más código, así que basado en tu presupuesto puedes usar supabase tambien.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvxb1nxon3nwn4h75b76t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvxb1nxon3nwn4h75b76t.png" alt="Image description" width="416" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fycolyn485rbko31ojqvv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fycolyn485rbko31ojqvv.png" alt="Image description" width="725" height="670"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vercel&lt;/strong&gt;:
Para configurar environments, fue muy sencillo poder asociar mi dominio con vercel y configurar subdominios con unos pocos clicks, si hubiera hecho esto desde cero por mi cuenta tendría que configurar https y agregar certificados validos con wildcards para soportar subdominios, aquí te permite crear subdominios con un certificado básico pero funciona para la version inicial de tu app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Namecheap&lt;/strong&gt;:
Ya tengo experiencia configurando las partes de básicas del dominio, subdomini, correo con google, etc.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Google&lt;/strong&gt;&lt;br&gt;
Para usar los servicios de correo de google, ya lo he configurado con namecheap, y es relativamente barato para iniciar y tener un correo profesional.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Docker&lt;/strong&gt;:&lt;br&gt;
No fue opcional, ya que es requerida por supabase para poder usarlo localmente.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Motivación
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Quería probar nuevas tecnologías.&lt;/li&gt;
&lt;li&gt;Quería crear un MVP.&lt;/li&gt;
&lt;li&gt;"Repentinamente" me quedé sin proyecto y ahora la idea del MVP no era opcional, pero es lo contaré en otro post.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Aplicación
&lt;/h2&gt;

&lt;p&gt;La aplicación es una web app, la idea inicial seria o es una app para digitalizar los menús en los restaurantes, los restaurantes podrían configurar los productos, sus precios, etc, agregar sucursales y asociar productos a sucursales. Parte de la idea inicial era que los consumidores pudieran ordenar desde la app, pero eso añadía una capa de complejidad que iba a demorar el lanzamiento del MVP, así que eso pasa a una segunda iteración&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdwiqflglhz62h0253se0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdwiqflglhz62h0253se0.png" alt="Image description" width="800" height="465"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Backoffice para restaurantes&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4lqmyf1fbghv3rp1yca0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4lqmyf1fbghv3rp1yca0.png" alt="Image description" width="432" height="952"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Aplicación de meńu para consumidores&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Criterios de decisión
&lt;/h2&gt;

&lt;p&gt;Queria que lo básico o repetitivo estuviera casi que por defecto, y asi poder practicar y aprender cosas nuevas o que casi no hago en mi trabajo regular.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Todo parte de la idea del MVP, lo cual de base necesitaba tecnologías que me permitieran iterar rápido.&lt;/li&gt;
&lt;li&gt;Tecnologías que me exigieran un poco más de conocimiento, en areas que no estoy familiarizado, como real-time, monorepositorios, Github actions, etc y a la vez usar las que ya conozco para no perder tiempo en eso.&lt;/li&gt;
&lt;li&gt;No queria perder tiempo en configuraciones repetitivas como autenticación, configuración de base de datos, APIs para un CRUD, etc.&lt;/li&gt;
&lt;li&gt;Necesitaba que el stack me permitiera tener buen performance por defecto.&lt;/li&gt;
&lt;li&gt;No quería perder tiempo en CSS y escribiendo estilos desde cero, ni crear componentes básicos desde cero, como botones, formularios, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;Si hoy alguien me preguntara que tecnologías recomiendo para inciar un MVP, destacaría 2: &lt;strong&gt;Supabase&lt;/strong&gt; y &lt;strong&gt;NextJS&lt;/strong&gt;, el resto puede variar.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;He grabado un video en el cual muestro un poco la aplicación:
&lt;a href="https://youtu.be/fyOKg2mjpTo" rel="noopener noreferrer"&gt;https://youtu.be/fyOKg2mjpTo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Configuración de dominios y subdominios con Namecheap y Vercel:
&lt;a href="https://youtu.be/IY05UEV6DJY" rel="noopener noreferrer"&gt;https://youtu.be/IY05UEV6DJY&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Introduction to Kubernetes (notes 1).</title>
      <dc:creator>Enmanuel Jarquín</dc:creator>
      <pubDate>Thu, 12 Sep 2024 00:45:02 +0000</pubDate>
      <link>https://dev.to/theenmanuel23/introduction-to-kubernetes-notes-1-513h</link>
      <guid>https://dev.to/theenmanuel23/introduction-to-kubernetes-notes-1-513h</guid>
      <description>&lt;p&gt;Course:&lt;br&gt;
&lt;a href="https://cloudacademy.com/course/introduction-to-kubernetes/introduction/?context_id=92&amp;amp;context_resource=lp" rel="noopener noreferrer"&gt;https://cloudacademy.com/course/introduction-to-kubernetes/introduction/?context_id=92&amp;amp;context_resource=lp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kubernetes is a container orchestration tool.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clusters: refers to all of the machines collectively and can be thought of as the entire running system.&lt;/li&gt;
&lt;li&gt;Nodes are the machines in the cluster.&lt;/li&gt;
&lt;li&gt;Nodes are categorized as workers or masters&lt;/li&gt;
&lt;li&gt;Worker nodes include software to run containers managed by the Kubernetes control plane.&lt;/li&gt;
&lt;li&gt;Master nodes run the control plane&lt;/li&gt;
&lt;li&gt;The control plane is a set of APIs and software that Kubernetes users interact with.&lt;/li&gt;
&lt;li&gt;The APIs and software are referred to as master components&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Scheduling:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Control plane schedules containers onto nodes.&lt;/li&gt;
&lt;li&gt;Scheduling decisions consider required CPU and other factors.&lt;/li&gt;
&lt;li&gt;Scheduling refers to the decision process of placing containers onto nodes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Kubernets Pods:&lt;/strong&gt;&lt;br&gt;
**- Containers are grouped onto pods.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pods can include one or more containers.&lt;/li&gt;
&lt;li&gt;All containers in a pod run on the same node.&lt;/li&gt;
&lt;li&gt;Pods are the smallest building block in Kubernetes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Services:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Services define networking rules for exposing groups of Pods&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To other pods&lt;/li&gt;
&lt;li&gt;To the public Internet&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Use labels to select a group of Pods.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Service has a fixed IP address.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Distribute requests across Pods in the group.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Kubernetes Deployments:&lt;/strong&gt;&lt;br&gt;
Manage deploying configuration changes to running Pods.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pods:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pods are Kubernetes' basic building block&lt;/li&gt;
&lt;li&gt;Declare Pods and other resources in manifest files&lt;/li&gt;
&lt;li&gt;metadata includes name and labels&lt;/li&gt;
&lt;li&gt;Pod &lt;em&gt;spec&lt;/em&gt; include container names, images&lt;/li&gt;
&lt;li&gt;Containers communicate over localhost within a Pod&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kubectl logs&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;logs record  what's written to standard output and standard error&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizontal scaling.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Introduction to Kubernetes (notes 2)</title>
      <dc:creator>Enmanuel Jarquín</dc:creator>
      <pubDate>Thu, 12 Sep 2024 00:44:33 +0000</pubDate>
      <link>https://dev.to/theenmanuel23/introduction-to-kubernetes-notes-2-o4m</link>
      <guid>https://dev.to/theenmanuel23/introduction-to-kubernetes-notes-2-o4m</guid>
      <description>&lt;h2&gt;
  
  
  Interacting with Kubernetes:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Method 1:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is possible but not common to work directly with the API server&lt;/li&gt;
&lt;li&gt;You might need to if there is no Kubernetes client library for your programming language.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Method 2: Client libraries&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Handles authenticating and managing individual REST API requests and responses.&lt;/li&gt;
&lt;li&gt;Maintains official client libraries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Method 3: kubectl&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Issue high-level commands that are translated into REST API calls.&lt;/li&gt;
&lt;li&gt;Wors with local and remote clusters&lt;/li&gt;
&lt;li&gt;Manages all different type of Kubernetes resources, and provides debugging and introspection features.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Method 4: Web Dashboard&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Pods
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What are Pods?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic building block in Kubernetes&lt;/li&gt;
&lt;li&gt;One or more containers in a Pod&lt;/li&gt;
&lt;li&gt;Pod containers all share a container network&lt;/li&gt;
&lt;li&gt;One IP address per Pod&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because Pods include containers, the declaration of a Pod includes all the properties that you would expect for example with Docker run.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Manifest Files&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Declare desired properties.&lt;/li&gt;
&lt;li&gt;Manifests can describe all kinds of resource&lt;/li&gt;
&lt;li&gt;The spec contains resource-specific properties.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Probes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Used to check when a pod is ready to serve traffic/handle requests&lt;/li&gt;
&lt;li&gt;Userful after startup to check external dependencies.&lt;/li&gt;
&lt;li&gt;Readiness Probes set the Pods's ready condition. Services only send traffic to ready Pods.&lt;/li&gt;
&lt;li&gt;Can be declared in a Pod's containers&lt;/li&gt;
&lt;li&gt;All cotainer probes must pass for the Pod to pass&lt;/li&gt;
&lt;li&gt;Probe actions can be a comand that runs in the container, an HTTP GET request, or opening a TCP socket.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Liveness Probes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Detect when a Pod enters a broken state.&lt;/li&gt;
&lt;li&gt;Kubernetes will restart the pod for you.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Init Containers:&lt;/strong&gt;&lt;br&gt;
Motivation for Init Contianers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sometimes you need to wait for a service, downaloads , dynamic or decisions before starting a Pods's containers.&lt;/li&gt;
&lt;li&gt;Prefer to separate initialization logic from the container image.&lt;/li&gt;
&lt;li&gt;Initialization is tightly coupled to the main application (belongs in the Pod)&lt;/li&gt;
&lt;li&gt;Kubernetes provides us with Init Containers that allow you to run initialization tasks before starting the main container(s)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Init Containers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pods can declare any number of init containers&lt;/li&gt;
&lt;li&gt;Init Containers run in order and to completion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;*&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User their own images&lt;/li&gt;
&lt;li&gt;Easy way to blcok or delay startring an application.&lt;/li&gt;
&lt;li&gt;Run every time a Pod is created&lt;/li&gt;
&lt;li&gt;They have the same fields as regular containers, except for &lt;code&gt;readinessProbe&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, Init Contianers allow you to perform tasks before main application containers have an opportunity to st art.&lt;br&gt;
They are useful for checking preconditions and preparing dependencies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Volumes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Volumenes are tied to a pod and their lifecycle.&lt;/li&gt;
&lt;li&gt;Share data between containers and tolerate container restarts&lt;/li&gt;
&lt;li&gt;Use for non-durable storage that is deleted with the Pod.&lt;/li&gt;
&lt;li&gt;Default Volumen type is &lt;code&gt;emptyDir&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Data is lost if Pod is rescheduled on a different node.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;ConfigMaps and Secrets:&lt;/strong&gt;&lt;br&gt;
ConfigMaps and secrets separte configuration data from pod specs or what would otherwise be stored in container images.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Both store data as key-value pairs.&lt;/li&gt;
&lt;li&gt;Secrets are for sensitive data.&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Vagrant and VMWare Fusion in Mac M1</title>
      <dc:creator>Enmanuel Jarquín</dc:creator>
      <pubDate>Sat, 20 Jul 2024 04:51:05 +0000</pubDate>
      <link>https://dev.to/theenmanuel23/vagrant-and-vmware-fusion-in-mac-m1-34dd</link>
      <guid>https://dev.to/theenmanuel23/vagrant-and-vmware-fusion-in-mac-m1-34dd</guid>
      <description>&lt;p&gt;Notes about installing Vagrant and VMWare Fusion on my Mac M1 with Sonoma.&lt;/p&gt;

&lt;p&gt;I tried to install Vagrant along with Virtual Box on my Mac M1, but I got several errors. So I decided to use VMWare leveraging I already use it with Windows 11.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install VMWare, this is my current version:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6q1gsuhgu6tmh1xpax19.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6q1gsuhgu6tmh1xpax19.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Download Vagrant and install it, I saw that you can install it via the command line using &lt;code&gt;brew&lt;/code&gt;. I just used the package that I downloaded from here: &lt;a href="https://developer.hashicorp.com/vagrant/install" rel="noopener noreferrer"&gt;https://developer.hashicorp.com/vagrant/install&lt;/a&gt;&lt;br&gt;
My current version is: &lt;code&gt;1.0.22&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install Vagrant utility for VMWare:&lt;br&gt;
&lt;a href="https://developer.hashicorp.com/vagrant/install/vmware" rel="noopener noreferrer"&gt;Vagrant Utility&lt;/a&gt;&lt;br&gt;
At the minute of writing down these notes the version I installed and that worked for is: &lt;code&gt;1.0.22&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install the vagrant plugin, just open the terminal and execute this command: &lt;code&gt;vagrant plugin install vagrant-vmware-desktop&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I restarted my system just in case.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify vagrant was installed: &lt;code&gt;vagrant --version&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open VMWare and keep it open, just in case.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a new directory, and create a new Vagrant file: &lt;code&gt;Vagrantfile&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Copy and paste this code:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Vagrant.configure("2") do |config|&lt;br&gt;
    config.vm.box = "spox/ubuntu-arm"&lt;br&gt;
    config.vm.box_version = "1.0.0"&lt;br&gt;
  end&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
10. Run: `vagrant up` on the directory of the newly file.
11. Add network configuration:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vagrant.configure("2") do |config|&lt;br&gt;
    config.vm.box = "spox/ubuntu-arm"&lt;br&gt;
    config.vm.box_version = "1.0.0"&lt;br&gt;
    config.vm.hostname = "testbox01"&lt;br&gt;
    config.vm.network "private_network", ip: "10.9.8.7"&lt;br&gt;
  end&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;12. I got an error saying something like: `Failed to create new device`
13. I found out that the error was that initialy I was using an old version of the vagrant utility for vmware: `1.0.21`, so I read this post:
https://github.com/hashicorp/vagrant/issues/12052
and there I saw that I needed to install the new version, in my case `1.0.22` which I mentioned on the point #3.

Kudos to this post: https://medium.com/@iamzamartech/create-and-manage-vms-with-vagrant-on-mac-m1-chip-d8b85eed082e, since most of the fixes or steps were taken from there.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>vagrant</category>
      <category>vmware</category>
      <category>m1</category>
      <category>mac</category>
    </item>
    <item>
      <title>Internationalization with Svelte and SvelteKit - Part 2</title>
      <dc:creator>Enmanuel Jarquín</dc:creator>
      <pubDate>Tue, 04 Jul 2023 04:02:08 +0000</pubDate>
      <link>https://dev.to/theenmanuel23/internationalization-with-svelte-and-sveltekit-part-2-4k6j</link>
      <guid>https://dev.to/theenmanuel23/internationalization-with-svelte-and-sveltekit-part-2-4k6j</guid>
      <description>&lt;p&gt;This is the second part of our previous article, you could find it &lt;a href="https://enmanueljarquin.com/internationalization-with-svelte-and-sveltekit-part-1"&gt;here&lt;/a&gt; if you haven't seen it, yet.&lt;/p&gt;

&lt;p&gt;Well, we have the &lt;code&gt;locale&lt;/code&gt; variable with a hardcoded value, now we'll add a new file at the same level of the &lt;code&gt;+layout.ts&lt;/code&gt; called &lt;code&gt;+.layout.server.ts&lt;/code&gt; , here we will write the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// +layout.server.ts
import type { LayoutServerLoad } from './$types';

export const load: LayoutServerLoad = () =&amp;gt; {
    return { locale: 'en' };
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we will change the content of the file &lt;code&gt;+layout.ts&lt;/code&gt; to read the value that we are returning from &lt;code&gt;+layout.server.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// +layout.ts
import type { LayoutLoad } from './$types';
import { loadLocaleAsync } from '../i18n/i18n-util.async';
import { setLocale } from '../i18n/i18n-svelte';

export const load: LayoutLoad = async (event) =&amp;gt; {
- const locale = 'es';    
+ const locale = event.data.locale;
    await loadLocaleAsync(locale);
    setLocale(locale);

    return event.data;
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our app should work as always, but we are still using a hardcoded value, but the difference is that it comes from our second file.&lt;/p&gt;

&lt;p&gt;What we want now is to read a &lt;code&gt;locale&lt;/code&gt; from the URL or from the browser directly, then pass it to the file &lt;code&gt;+layout.server.ts&lt;/code&gt; and this in turn will pass it to the &lt;code&gt;+.layout.ts&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;To accomplish the mentioned above, we need to add another file called &lt;code&gt;hooks.server.ts&lt;/code&gt; but in this case in the &lt;code&gt;src&lt;/code&gt; directory: &lt;code&gt;src/hooks.server.ts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We are going to do something quite similar to what we did when we created the file &lt;code&gt;+layout.server.ts&lt;/code&gt;, we are going to hardcode the &lt;code&gt;lang&lt;/code&gt; but now in the file &lt;code&gt;hooks.server.ts&lt;/code&gt; and within a function called &lt;code&gt;handle&lt;/code&gt; that we should return.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/hooks.server.ts
import type { Handle } from '@sveltejs/kit';

export const handle: Handle = async ({ event, resolve }) =&amp;gt; {
    event.locals.locale = 'es';
    return resolve(event);
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in the file &lt;code&gt;+layout.server.ts&lt;/code&gt; we need to read the object &lt;code&gt;locals&lt;/code&gt; and its property &lt;code&gt;locale&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/routes/+layout.server.ts
export const load: LayoutServerLoad = ({ locals }) =&amp;gt; {
    return { locale: locals.locale };
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we change from &lt;code&gt;es&lt;/code&gt; to &lt;code&gt;en&lt;/code&gt; and vice-versa, everything should work as always.&lt;/p&gt;

&lt;p&gt;Now to remove the hardcoded lang, we will make use of the params in the URL, one more time, go ahead to our file &lt;code&gt;hooks.server.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/hooks.server.ts
import type { Handle } from '@sveltejs/kit';

export const handle: Handle = async ({ event, resolve }) =&amp;gt; {
- event.locals.locale = 'es';
+ const lang = event.url.searchParams.get('lang');
+ event.locals.locale = lang || 'en';
    return resolve(event);
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To test it, we should modify the URL in the browser: &lt;a href="http://localhost:5173/?lang=es"&gt;http://localhost:5173/?lang=es&lt;/a&gt;, if any lang is passed, then it will show the default language, in this case &lt;code&gt;english&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;Perfect, now we can pass what language we want to use by specifying it in the URL&lt;/p&gt;

&lt;h3&gt;
  
  
  Reading the browser language
&lt;/h3&gt;

&lt;p&gt;Now, we want to do is remove the default hardcoded language set as &lt;code&gt;english&lt;/code&gt; and replace it with the default language from the browser, we should use the function &lt;code&gt;initAcceptLanguageHeaderDetector&lt;/code&gt; in the file &lt;code&gt;hooks.server.ts&lt;/code&gt;, so, let's do it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/hooks.server.ts
const getPreferredLocale = ({ request }: RequestEvent) =&amp;gt; {
  const acceptLanguageDetector = initAcceptLanguageHeaderDetector(request);
  return detectLocale(acceptLanguageDetector);
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We must add some &lt;code&gt;imports&lt;/code&gt; as well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/hooks.server.ts
// import type { Handle } from '@sveltejs/kit';
+ import type { Handle, RequestEvent } from '@sveltejs/kit';
+ import { detectLocale, i18n, isLocale } from './i18n/i18n-util';
+ import { initAcceptLanguageHeaderDetector } from 'typesafe-i18n/detectors';

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we need to update the function &lt;code&gt;handle&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/hooks.server.ts
export const handle: Handle = async ({ event, resolve }) =&amp;gt; {
    const lang = event.url.searchParams.get('lang');

// event.locals.locale = lang || 'en';
+ event.locals.locale = lang || getPreferredLocale(event);

    return resolve(event);
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now in my case, I have Spanish as my default language in Chrome:&lt;code&gt;Settings/Languages&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0yU-_6MB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1688441037858/294d12e5-a077-4ecf-9068-9bb28c7a2b33.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0yU-_6MB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1688441037858/294d12e5-a077-4ecf-9068-9bb28c7a2b33.png" alt="Default Chrome Language" width="760" height="163"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If I don't pass any language in the URL, it will read this default language from the browser directly.&lt;/p&gt;

&lt;p&gt;Cool!, We are almost done, but there is still an improvement that we could do, for example, if I pass the &lt;code&gt;lang&lt;/code&gt; param via the URL but it doesn't exist in my configuration, it won't read the default browser language because the param &lt;code&gt;lang&lt;/code&gt; in the URL was set, but it is an invalid &lt;code&gt;lang&lt;/code&gt;, if we leave it as it is so right now we will get a pretty 500 error:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://localhost:5173/?lang=ed"&gt;http://localhost:5173/?lang=ed&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well to fix that we could add validation for the &lt;code&gt;lang&lt;/code&gt; that was provided to us:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/hooks.server.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Locales&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./i18n/i18n-types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Handle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;    
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;isLocale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lang&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Locales&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lang&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Locales&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;getPreferredLocale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;locales&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's how we fixed it, we use &lt;code&gt;isLocale&lt;/code&gt; to validate the &lt;code&gt;lang&lt;/code&gt;, if it is a valid &lt;code&gt;lang&lt;/code&gt;, then we use it as a value of &lt;code&gt;locale&lt;/code&gt; if not, then we read it from the default browser lang.&lt;/p&gt;

&lt;p&gt;In our next post, we are going to add a button or link to switch the language, that will be our third option to use this feature. See you there and happy coding!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Internationalization with Svelte and SvelteKit - Part 1</title>
      <dc:creator>Enmanuel Jarquín</dc:creator>
      <pubDate>Tue, 27 Jun 2023 03:25:59 +0000</pubDate>
      <link>https://dev.to/theenmanuel23/internationalization-with-svelte-and-sveltekit-parte-1-1in</link>
      <guid>https://dev.to/theenmanuel23/internationalization-with-svelte-and-sveltekit-parte-1-1in</guid>
      <description>&lt;p&gt;Internationalization support could be an easy task, you can easily create objects and then get the proper language by a key, but if you want to create a solid project in the long run, sooner or later you are going to have to face some challenges.&lt;/p&gt;

&lt;p&gt;There are some options to set the proper language of a site, it could be by reading a query param from the URL or getting the browser lang config, or by selecting it from a select or dropdown component.&lt;/p&gt;

&lt;p&gt;I played with two different libraries:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/sveltekit-i18n/lib" rel="noopener noreferrer"&gt;https://github.com/sveltekit-i18n/lib&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/ivanhofer/typesafe-i18n" rel="noopener noreferrer"&gt;https://github.com/ivanhofer/typesafe-i18n&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The one I liked was the second one, &lt;code&gt;typesafe-i18n&lt;/code&gt;, it includes a lot of features out-the-box, so on this occasion, I would like to walk you through the installation of this tool to create a multi-language app.&lt;/p&gt;

&lt;h3&gt;
  
  
  First and foremost, create a svelte-kit project:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm create svelte@latest i18n-sveltekit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some of the options that I selected are shown in the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1687828474427%2Fda13ce2f-7b32-444f-8266-92c7183b6418.png%2520align%3D" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1687828474427%2Fda13ce2f-7b32-444f-8266-92c7183b6418.png%2520align%3D" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing and configuring typesafe-i18n
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; typesafe-i18n
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we need to run the setup process, we can do it by a manual process by answering questions or generating the configuration automatically, so we are going for the automatic setup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx typesafe-i18n &lt;span class="nt"&gt;--setup-auto&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That command will generate the file &lt;code&gt;.typesafe-i18n.json&lt;/code&gt;, we will ensure that we have the key &lt;code&gt;adapter=svelte&lt;/code&gt;, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"adapter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"svelte"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"$schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://unpkg.com/typesafe-i18n@5.24.3/schema/typesafe-i18n.json"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and our &lt;code&gt;package.json&lt;/code&gt; file was updated with a new script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="s2"&gt;"scripts"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"typesafe-i18n"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"typesafe-i18n"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's run it and see what happens:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run typesafe-i18n
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we open the project structure again, we are going to find out that we have new folders and files inside of them:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1687830691759%2F1224711a-b403-47db-a5ed-6204a7825a13.png%2520align%3D" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1687830691759%2F1224711a-b403-47db-a5ed-6204a7825a13.png%2520align%3D" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That command/script generated all the configuration we need to support the internationalization feature in our app, but there are still some steps that we need to do to customize how we are going to switch between languages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Running the app and typesafe-i18n
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;typesafe-i18n&lt;/code&gt; needs to update the files seen above, so it will work in real-time since it generates types, configurations, etc, at the same time we are running our development server, that being said, let's install another package to accomplish that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;npm-run-all &lt;span class="nt"&gt;-D&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we will update our &lt;code&gt;package.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- "dev": "vite dev",
&lt;/span&gt;&lt;span class="gi"&gt;+ "dev": "npm-run-all --parallel typesafe-i18n vite:dev",
+ "vite:dev": "vite dev",
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, if we run the script &lt;code&gt;npm run dev&lt;/code&gt; , you will see that our script runs the &lt;code&gt;typesafe-i18n&lt;/code&gt; configuration and our &lt;code&gt;development server&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1687831891300%2Ff69f4950-077b-4560-983d-5447a1e76e04.png%2520align%3D" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1687831891300%2Ff69f4950-077b-4560-983d-5447a1e76e04.png%2520align%3D" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's get down to the nitty-gritty
&lt;/h3&gt;

&lt;p&gt;Now we can start adding support for &lt;code&gt;english&lt;/code&gt; by default:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Head to the file &lt;code&gt;src/i18n/en/index.ts&lt;/code&gt; and add a new key that says &lt;code&gt;welcome&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...,&lt;/span&gt;
  &lt;span class="nx"&gt;welcome&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;to your new SvelteKit app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;When you save it, you will immediately see a change in the file &lt;code&gt;src/i18n/i18n-types.ts&lt;/code&gt; where our &lt;code&gt;welcome&lt;/code&gt; key was added, so, that will help us a lot to autocomplete our objects in real-time thanks to &lt;code&gt;typesafe-i18n&lt;/code&gt; and &lt;code&gt;typescript&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Let's create a &lt;code&gt;+layout.ts&lt;/code&gt; file inside of &lt;code&gt;src/routes/&lt;/code&gt; with the following content:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;LayoutLoad&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./$types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;loadLocaleAsync&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../i18n/i18n-util.async&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;setLocale&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../i18n/i18n-svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;load&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;LayoutLoad&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;loadLocaleAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;setLocale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We set &lt;code&gt;locale&lt;/code&gt; to &lt;code&gt;en&lt;/code&gt; manually, but we are going to change it in a few minutes, for now, what we are interested in is being able to load our basic configuration and test if it is working.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In our &lt;code&gt;src/routes/+page.svelte&lt;/code&gt; let's locale the line that says &lt;code&gt;to your new SvelteKit app&lt;/code&gt; , and we will change with this new line:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;First, add this import:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;LL&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../i18n/i18n-svelte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, change the line and add this content instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;$LL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;welcome&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that change placed, you should be able to see the text in a single line in your app:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1687833810034%2F385f3885-db17-47c9-8774-c9b197f38ebb.png%2520align%3D" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1687833810034%2F385f3885-db17-47c9-8774-c9b197f38ebb.png%2520align%3D" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1687833828181%2F5edc162d-5d6c-48d5-b950-f84c359ddc12.png%2520align%3D" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1687833828181%2F5edc162d-5d6c-48d5-b950-f84c359ddc12.png%2520align%3D" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will notice that the text now is occupying a single line instead of two, we need to fix that, but what matters here is the fact that our internationalization config is working and we can add a new language, let's add support for &lt;code&gt;spanish&lt;/code&gt; .&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding support for Spanish
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Remove the unused directory &lt;code&gt;src/i18n/de&lt;/code&gt; '&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add this folder and its index file: &lt;code&gt;src/i18n/es/index.ts&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the following content:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Translation&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../i18n-types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;es&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;welcome&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a tu nueva aplicacion en SvelteKit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;satisfies&lt;/span&gt; &lt;span class="nx"&gt;Translation&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;es&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Let's change the &lt;code&gt;locale&lt;/code&gt; variable of our &lt;code&gt;src/routes/+layout.ts&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- const locale = 'en';
&lt;/span&gt;&lt;span class="gi"&gt;+ const locale = 'es';
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, you will see that text in our app is shown in Spanish:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1687834514204%2F3b0dc772-4864-4bd1-9726-8878753cc3f8.png%2520align%3D" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1687834514204%2F3b0dc772-4864-4bd1-9726-8878753cc3f8.png%2520align%3D" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our multi-language app is almost ready, but we still need to add a way to change the language dynamically and allow users to change it manually, since what we have to do to accomplish it is by changing the &lt;code&gt;locale&lt;/code&gt; variable to switch between &lt;code&gt;english&lt;/code&gt; and &lt;code&gt;spanish&lt;/code&gt; , so let's do it in the second part.&lt;/p&gt;

</description>
      <category>sveltekit</category>
      <category>internationalization</category>
      <category>svelte</category>
      <category>i18n</category>
    </item>
    <item>
      <title>Tools for my web development env</title>
      <dc:creator>Enmanuel Jarquín</dc:creator>
      <pubDate>Tue, 20 Jun 2023 02:34:46 +0000</pubDate>
      <link>https://dev.to/theenmanuel23/tools-for-my-web-development-env-oi1</link>
      <guid>https://dev.to/theenmanuel23/tools-for-my-web-development-env-oi1</guid>
      <description>&lt;p&gt;Original Post: &lt;a href="https://enmanueljarquin.com/tools-for-my-web-development-env"&gt;https://enmanueljarquin.com/tools-for-my-web-development-env&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I enjoy working using my terminal on Mac, so I would like to write down and share some tools I use daily.&lt;/p&gt;

&lt;p&gt;I don't pretend to explain how to install and/or configure them since there are lots of steps that I would need to share, so the easiest way for me to share it is via the GitHub repo.&lt;/p&gt;




&lt;p&gt;Basic configuration with default configuration for &lt;strong&gt;React&lt;/strong&gt; support:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/TheEnmanuel23/development-config/tree/master"&gt;https://github.com/TheEnmanuel23/development-config/tree/master&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Extra configuration with &lt;strong&gt;Svelte&lt;/strong&gt; support:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/TheEnmanuel23/development-config/pull/1"&gt;https://github.com/TheEnmanuel23/development-config/pull/1&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Iterm2 along with Tmux
&lt;/h3&gt;

&lt;p&gt;To manage terminal sessions, tabs, panels, etc. I use it with &lt;code&gt;tmux-theme pack&lt;/code&gt; plugin to add some plugins and configure them, for example, I use the theme &lt;code&gt;powerline/default/cyan&lt;/code&gt; via &lt;code&gt;jimeh/tmux-themepack&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Read more: &lt;a href="https://github.com/jimeh/tmux-themepack"&gt;https://github.com/jimeh/tmux-themepack&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  NVIM
&lt;/h3&gt;

&lt;p&gt;Here some basic plugins help us to pave the way for the rest of the plugins that I am going to mention below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Lua&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Packer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LSP&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mason&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;1 &lt;strong&gt;Basic NVIM plugins&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/wbthomason/packer.nvim"&gt;Packer&lt;/a&gt;: Packer manager written in Lua&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/svrana/neosolarized.nvim"&gt;Neosolarized&lt;/a&gt;: Optional nvim theme, I sometimes change it to use &lt;code&gt;nightfly&lt;/code&gt; theme, I am not using it for now, since I use &lt;code&gt;nightfly&lt;/code&gt; .&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/christoomey/vim-tmux-navigator"&gt;Vim-tmux-navigator:&lt;/a&gt; Consistent way to navigate between tmux and vim panels.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/declancm/maximize.nvim"&gt;Maximize&lt;/a&gt;: Toggle maximizing the current neovim window without any of the ugly borders that other.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/kylechui/nvim-surround"&gt;Surround&lt;/a&gt;: To surround selection by using some extremely useful keys.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/numToStr/Comment.nvim"&gt;Comment&lt;/a&gt;: To comment snippets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/nvim-lua/plenary.nvim"&gt;Plenary&lt;/a&gt;: Common utilities, some plugins require it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/phaazon/hop.nvim"&gt;Hop&lt;/a&gt;: To jump anywhere in the current buffer by highlighting words, lines, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/nvim-tree/nvim-web-devicons"&gt;Web-devicons:&lt;/a&gt; Help to add icons to various plugins, like nvim tree, telescope, file browsers, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/nvim-lualine/lualine.nvim"&gt;Lualine&lt;/a&gt;: Statusline for nvim written in Lua.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/nvim-telescope/telescope.nvim"&gt;Telescope&lt;/a&gt;: It is an awesome finder over lists.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/nvim-telescope/telescope-file-browser.nvim"&gt;Telescope file browser:&lt;/a&gt; It is telescope extension that acts as a file browser, it allows us shortcuts to create, delete, rename and move files or folders. It could be used as a nvim-tree alternative.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/norcalli/nvim-colorizer.lua"&gt;nvim-colorizer:&lt;/a&gt; To highlight colors of css files for example.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/lewis6991/gitsigns.nvim"&gt;gitsigns:&lt;/a&gt; Git decorations on the vertical bar of the left section of a nvim panel that shows indicators based on the git status.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/akinsho/toggleterm.nvim"&gt;Toggleterm&lt;/a&gt;: To show floating terminals or multiple orientations during an editing session.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/bluz71/vim-nightfly-colors"&gt;vim-nightfly-colors&lt;/a&gt;: Dark nvim theme, as an alternative for &lt;code&gt;neosolarized&lt;/code&gt; theme. I am using it right now.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/startup-nvim/startup.nvim"&gt;startup&lt;/a&gt;: A customizable startup window.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;2 &lt;strong&gt;Autocompletion nvim plugins:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/hrsh7th/cmp-buffer"&gt;cmp-buffer&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/hrsh7th/cmp-path"&gt;cmp-path&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/hrsh7th/nvim-cmp"&gt;nvim-cmp&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3 &lt;strong&gt;Snippets nvim plugins:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/L3MON4D3/LuaSnip"&gt;LuaSnip&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[cmp_luasnip]&lt;a href="https://github.com/saadparwaiz1/cmp_luasnip"&gt;https://github.com/saadparwaiz1/cmp_luasnip&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[friendly-snippets (&lt;a href="https://github.com/rafamadriz/friendly-snippets"&gt;https://github.com/rafamadriz/friendly-snippets&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;4 &lt;strong&gt;Auto closing nvim plugins:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/windwp/nvim-autopairs"&gt;nvim-autopairs&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/windwp/nvim-ts-autotag"&gt;nvim-ts-autotag&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;5 &lt;strong&gt;Lsp servers to support typescript, react, tailwindcss and svelte:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/neovim/nvim-lspconfig"&gt;neovim/nvim-lspconfig&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/hrsh7th/nvim-cmp"&gt;hrsh7th/cmp-nvim-lsp&lt;/a&gt;: nvim-cmp source for neovim's built-in LSP&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/nvimdev/lspsaga.nvim#example-configuration"&gt;glepnir/lspsaga.nvim&lt;/a&gt;: With an enhanced UI, this helps us to configure shortcuts and popups to navigate our code by jumping to functions or variable definitions, renaming variables, fixing imports, among other benefits.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/onsails/lspkind.nvim"&gt;onsails/lspkind-nvim&lt;/a&gt;: Used to show icons to autocompletion windows or popups.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/jose-elias-alvarez/typescript.nvim"&gt;jose-elias-alvarez/typescript.nvim&lt;/a&gt;: Add further functionalities for typescript server like renaming a file or updating imports, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/nvim-treesitter/nvim-treesitter"&gt;nvim-treesitter/nvim-treesitter&lt;/a&gt;: It provides us a better interface for neovim with some basic functionalities such as highlighting.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;6 &lt;strong&gt;To install LSP plugins using Mason:&lt;/strong&gt; It helps to map, and install &lt;code&gt;lsp-servers&lt;/code&gt;, linters and formatters, besides it helps us to register setup hooks with lspconfig, it is a complement for &lt;strong&gt;LSP&lt;/strong&gt;, it acts as a bridge, closing some gaps between mason and lspconfig.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/williamboman/mason-lspconfig.nvim"&gt;williamboman/mason.nvim&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/williamboman/mason-lspconfig.nvim"&gt;williamboman/mason-lspconfig.nvim&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;7 &lt;strong&gt;Formatting and linting:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/jose-elias-alvarez/null-ls.nvim"&gt;jose-elias-alvarez/null-ls.nvim&lt;/a&gt;: To have code diagnostics, code actions, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/jay-babu/mason-null-ls.nvim"&gt;jay-babu/mason-null-ls.nvim&lt;/a&gt;: A better way to interact with &lt;code&gt;mason&lt;/code&gt; and &lt;code&gt;null-ls&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Other tools
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/koekeishiya/yabai"&gt;Yabai&lt;/a&gt;: Yabai is a window management utility for mac.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://minbrowser.org/"&gt;&lt;strong&gt;Min&lt;/strong&gt;&lt;/a&gt;: As my default browser for things that have nothing to do with development, to develop I use Chrome for its dev-tools.&lt;/p&gt;

&lt;p&gt;I have it configured to use &lt;code&gt;vim&lt;/code&gt; shortcuts to facilitate the navigation as the same way I would do with a vim buffer or file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/PalmerAL/min-vim-mode"&gt;https://github.com/PalmerAL/min-vim-mode&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.raycast.com/"&gt;&lt;strong&gt;Ratcast&lt;/strong&gt;&lt;/a&gt;: My default spotlight option, it is an awesome tools, since you can configure basically whatever you want, e.g.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;I configured it to check my JIRA's ticket's status without opening a new chrome tab.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To pick a color from anywhere in the screen&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;With google translate, I am not a native english speaker, so sometimes I need to figure out the meaning of the word, so with tool I don't need to open chrome or anther browser to open google translate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To create floating notes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To check my github repositories&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To check my agenda based on my default calendar.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To install packages with brew&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To interact with spotify&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;etc, etc, etc&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are some tools I use for my development environment and that I use daily.&lt;/p&gt;

&lt;p&gt;I would like to thank &lt;a href="https://www.youtube.com/@joseanmartinez"&gt;Josean Martinez&lt;/a&gt;, I learned a lot watching his videos, and I strongly recommend following him, he has an awesome youtube channel. &lt;a href="https://www.youtube.com/@joseanmartinez"&gt;https://www.youtube.com/@joseanmartinez&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nvim</category>
      <category>frontend</category>
      <category>tmux</category>
      <category>react</category>
    </item>
    <item>
      <title>Autosuggestions with oh-my-zsh</title>
      <dc:creator>Enmanuel Jarquín</dc:creator>
      <pubDate>Mon, 20 Dec 2021 06:29:16 +0000</pubDate>
      <link>https://dev.to/theenmanuel23/autosuggestions-with-oh-my-zsh-11i6</link>
      <guid>https://dev.to/theenmanuel23/autosuggestions-with-oh-my-zsh-11i6</guid>
      <description>&lt;p&gt;New Macs already include &lt;code&gt;zsh&lt;/code&gt; by default, so what we only need is to run the following command:&lt;/p&gt;

&lt;h4&gt;
  
  
  Install oh-my-zsh
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first step created us the following the &lt;code&gt;/.oh-my-zsh&lt;/code&gt; directory&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$ZSH_CUSTOM&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /Users/&amp;lt;your home directory&amp;gt;/.oh-my-zsh/custom
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Install autosuggestions plugin
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/zsh-users/zsh-autosuggestions &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ZSH_CUSTOM&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="p"&gt;~/.oh-my-zsh/custom&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/plugins/zsh-autosuggestions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That command will copy the zsh-autosuggestions repo into &lt;code&gt;/Users/&amp;lt;your home directory&amp;gt;/.oh-my-zsh/custom/plugins&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now we are going to add new plugin by opening the file &lt;code&gt;~/.zshrc&lt;/code&gt; and add the &lt;code&gt;zsh-autosuggestions&lt;/code&gt; plugin without commas&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;plugins=( 
    # other plugins...
    zsh-autosuggestions
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart your terminal and now when you type a command that you used previously you will see that now it will auto suggest you using a gray text.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnlq9kjrn8q6r7nlbc9ne.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnlq9kjrn8q6r7nlbc9ne.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>zsh</category>
      <category>osx</category>
      <category>ohmyzsh</category>
    </item>
  </channel>
</rss>
