<?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>Forem: Francisco GSilva</title>
    <description>The latest articles on Forem by Francisco GSilva (@francgs).</description>
    <link>https://forem.com/francgs</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%2F1123046%2Fb8d5a15e-044d-41b4-af67-b99a2acfd0f4.jpeg</url>
      <title>Forem: Francisco GSilva</title>
      <link>https://forem.com/francgs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/francgs"/>
    <language>en</language>
    <item>
      <title>Real Bilingual Blog Refactor: Routes, hreflang, and Consistent SEO</title>
      <dc:creator>Francisco GSilva</dc:creator>
      <pubDate>Wed, 11 Feb 2026 12:11:54 +0000</pubDate>
      <link>https://forem.com/francgs/real-bilingual-blog-refactor-routes-hreflang-and-consistent-seo-l1p</link>
      <guid>https://forem.com/francgs/real-bilingual-blog-refactor-routes-hreflang-and-consistent-seo-l1p</guid>
      <description>&lt;h1&gt;
  
  
  Real Bilingual Blog Refactor: Routes, hreflang, and Consistent SEO
&lt;/h1&gt;

&lt;p&gt;Building a bilingual blog is not just translation work. If route architecture, canonical strategy, and navigation are not aligned, you get duplicate content, indexing confusion, and users landing in mixed-language sections.&lt;/p&gt;

&lt;p&gt;This refactor solved that from end to end. Here is the practical walkthrough.&lt;/p&gt;

&lt;h2&gt;
  
  
  Initial Problem
&lt;/h2&gt;

&lt;p&gt;We had clear symptoms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/blog&lt;/code&gt; was mixing Spanish and English posts,&lt;/li&gt;
&lt;li&gt;old non-localized URLs were still active,&lt;/li&gt;
&lt;li&gt;direct URL visitors did not get consistent language behavior,&lt;/li&gt;
&lt;li&gt;Search Console showed canonical conflicts and duplicates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Goal: language-consistent UX and crawl-friendly SEO.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture Decisions
&lt;/h2&gt;

&lt;p&gt;We standardized around five rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Language-first routes: &lt;code&gt;/{lang}/...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Smart redirects for generic routes (&lt;code&gt;/&lt;/code&gt;, &lt;code&gt;/blog&lt;/code&gt;, &lt;code&gt;/tags&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Per-post &lt;code&gt;hreflang&lt;/code&gt; + &lt;code&gt;x-default&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Language preference cookie (&lt;code&gt;site_lang&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Localized pages for home, tags, and category hubs&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 1: Localized Pages
&lt;/h2&gt;

&lt;p&gt;We implemented language-aware pages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;src/pages/[lang]/index.astro&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;src/pages/[lang]/blog/[...slug].astro&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;src/pages/[lang]/blog/index.astro&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;src/pages/[lang]/blog/category/index.astro&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;src/pages/[lang]/tags/index.astro&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;src/pages/[lang]/tags/[tag].astro&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This removes ambiguity and makes language explicit in every route.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Middleware Redirect Strategy
&lt;/h2&gt;

&lt;p&gt;Middleware now resolves language from cookie + &lt;code&gt;Accept-Language&lt;/code&gt;, then redirects generic routes.&lt;/p&gt;

&lt;p&gt;Simplified logic:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;preferredLang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cookieLang&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nf"&gt;detectLangFromHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acceptLanguageHeader&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;normalizedPath&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&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;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;preferredLang&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;302&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;normalizedPath&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/blog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&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;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;preferredLang&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/blog/`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;302&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;Result: no more mixed-language listing pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Canonical and hreflang
&lt;/h2&gt;

&lt;p&gt;We extended SEO metadata to include language alternates:&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;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;LanguageAlternateEntry&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&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;Per post, alternates are computed by &lt;code&gt;translationKey&lt;/code&gt; and include &lt;code&gt;x-default&lt;/code&gt;.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;alternates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;translations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;lang&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="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;siteUrl&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="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/blog/&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="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;alternates&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;x-default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;siteUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;en/blog/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;defaultId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/`&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives search engines explicit language mapping and reduces canonical ambiguity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Navigation Consistency
&lt;/h2&gt;

&lt;p&gt;The header was updated to preserve language context:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Home -&amp;gt; &lt;code&gt;/${lang}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Tags -&amp;gt; &lt;code&gt;/${lang}/tags&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Categories -&amp;gt; &lt;code&gt;/${lang}/blog/category&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We also added an explicit &lt;code&gt;ES | EN&lt;/code&gt; switcher and persist user choice via cookie.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Remove Duplicate "Related" UX
&lt;/h2&gt;

&lt;p&gt;Some migrated posts had both:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;markdown “Related” link list,&lt;/li&gt;
&lt;li&gt;visual related-posts component.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That created duplicated sections and visual noise. We removed markdown duplicates and kept the component-based related cards.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Translation Coverage Report
&lt;/h2&gt;

&lt;p&gt;To prevent ES/EN drift, we added a coverage report:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm run seo:report-translations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docs/seo/translation-coverage.md&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This catches incomplete translation keys before release.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7: QA Checklist After Refactor
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;code&gt;/blog&lt;/code&gt; redirects to &lt;code&gt;/{lang}/blog/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;/tags&lt;/code&gt; redirects to &lt;code&gt;/{lang}/tags/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] post canonical matches localized URL&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;hreflang&lt;/code&gt; includes ES/EN + &lt;code&gt;x-default&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] no mixed-language listing pages&lt;/li&gt;
&lt;li&gt;[ ] build passes cleanly&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common Mistakes in Bilingual Refactors
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Translating content but keeping non-localized URLs.&lt;/li&gt;
&lt;li&gt;Localized routes without metadata parity.&lt;/li&gt;
&lt;li&gt;Navigation that breaks language context.&lt;/li&gt;
&lt;li&gt;Redirect chains without a clear policy.&lt;/li&gt;
&lt;li&gt;No automated translation coverage audit.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Publishing Opportunities From This Refactor
&lt;/h2&gt;

&lt;p&gt;This refactor itself can become a technical series:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Language route architecture in Astro.&lt;/li&gt;
&lt;li&gt;Practical international SEO: canonical + hreflang.&lt;/li&gt;
&lt;li&gt;Migration strategy that preserves indexing stability.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Close
&lt;/h2&gt;

&lt;p&gt;The biggest win was not “having two languages.” The real win was consistency across user navigation, metadata, and crawl behavior.&lt;/p&gt;

&lt;p&gt;If you are planning a similar migration, do not start with translation copywriting. Start with route architecture, canonical strategy, and redirect behavior.&lt;/p&gt;

&lt;p&gt;Related:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/en/blog/49-como-construimos-un-sistema-de-sincronizacion-automatizada-devto-medium-en/"&gt;&lt;code&gt;/en/blog/49-como-construimos-un-sistema-de-sincronizacion-automatizada-devto-medium-en/&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/en/blog/31-typescript-avanzado-patrones-reales-y-tradeoffs-en/"&gt;&lt;code&gt;/en/blog/31-typescript-avanzado-patrones-reales-y-tradeoffs-en/&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/en/blog/category/web-development/"&gt;&lt;code&gt;/en/blog/category/web-development/&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>seo</category>
      <category>astro</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Configurar un nuevo sitio web en NGINX</title>
      <dc:creator>Francisco GSilva</dc:creator>
      <pubDate>Wed, 11 Feb 2026 02:57:42 +0000</pubDate>
      <link>https://forem.com/francgs/configurar-un-nuevo-sitio-web-en-nginx-44mp</link>
      <guid>https://forem.com/francgs/configurar-un-nuevo-sitio-web-en-nginx-44mp</guid>
      <description>&lt;h1&gt;
  
  
  Configurar un nuevo sitio web en NGINX
&lt;/h1&gt;

&lt;p&gt;Seguir los siguientes comando:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;crear folder del sitio&lt;br&gt;
&lt;code&gt;sudo mkdir -p /var/www/{your-domain}/&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Asignamos el usuario dueño del folder&lt;br&gt;
&lt;code&gt;sudo chown -R $USER:$USER /var/www/{your-domain}/&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Asignamos permisos&lt;br&gt;
&lt;code&gt;sudo chmod -R 755 /var/www/{your-domain}/&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creamos un index.html file a modo de prueba&lt;br&gt;
&lt;code&gt;sudo nano /var/www/{your-domain}/index.html&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Contenido del archivo index.html&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Welcome to your-domain!&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Success!  The your-domain server block is working!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Para que Nginx pueda servir este contenido, es necesario crear un server block con las directivas correctas. En lugar de modificar el archivo de configuración predeterminado directamente, hagamos uno nuevo en /etc/nginx/sites-available/{your-domain}:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;sudo nano /etc/nginx/sites-available/{your-domain}&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;El contenido del archivo de configuración:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="s"&gt;[::]:80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/var/www/your_domain&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;index&lt;/span&gt; &lt;span class="s"&gt;index.html&lt;/span&gt; &lt;span class="s"&gt;index.htm&lt;/span&gt; &lt;span class="s"&gt;index.nginx-debian.html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;your_domain&lt;/span&gt; &lt;span class="s"&gt;www.your_domain&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kn"&gt;try_files&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt;&lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;404&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;ol&gt;
&lt;li&gt;A continuación, vamos a habilitar el archivo creando un enlace desde este al directorio sites-enabled, del cual Nginx lee durante el inicio:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;NOTA:&lt;/em&gt;&lt;/strong&gt; Nginx utiliza una práctica común llamada enlaces simbólicos, o symlinks, para rastrear cuáles de tus bloques de servidor están habilitados. Crear un symlink es como crear un acceso directo en el disco, de modo que más tarde podrías eliminar el acceso directo del directorio sites-enabled mientras mantienes el bloque de servidor en sites-available si quisieras habilitarlo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Para evitar un posible problema de memoria del hash bucket que puede surgir al agregar nombres de servidor adicionales, es necesario ajustar un solo valor en el archivo /etc/nginx/nginx.conf. Abre el archivo:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;sudo nano /etc/nginx/nginx.conf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Encuentra la directiva &lt;code&gt;server_names_hash_bucket_size&lt;/code&gt; y elimina el símbolo &lt;code&gt;#&lt;/code&gt; para descomentar la línea. Si estás usando nano, puedes buscar rápidamente palabras en el archivo presionando &lt;code&gt;CTRL&lt;/code&gt; y &lt;code&gt;w&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Verifica que el archivo de configuración no contenga errores: &lt;code&gt;sudo nginx -t&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reiniciamos el servicio de nginx &lt;code&gt;sudo systemctl restart nginx&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Subtitulo
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Otro subtitulo
&lt;/h3&gt;

</description>
      <category>linux</category>
      <category>nginx</category>
      <category>devops</category>
    </item>
    <item>
      <title>Fix to Key</title>
      <dc:creator>Francisco GSilva</dc:creator>
      <pubDate>Wed, 11 Feb 2026 02:49:56 +0000</pubDate>
      <link>https://forem.com/francgs/fix-to-key-43d4</link>
      <guid>https://forem.com/francgs/fix-to-key-43d4</guid>
      <description>&lt;h1&gt;
  
  
  Fix to Key
&lt;/h1&gt;

&lt;p&gt;error: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY A8580BDC82D3DC6C&lt;/p&gt;

&lt;p&gt;solución:&lt;/p&gt;

&lt;p&gt;sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys A8580BDC82D3DC6C&lt;/p&gt;

</description>
      <category>linux</category>
      <category>troubleshooting</category>
    </item>
    <item>
      <title>Set Up a New Website in NGINX</title>
      <dc:creator>Francisco GSilva</dc:creator>
      <pubDate>Wed, 11 Feb 2026 02:49:55 +0000</pubDate>
      <link>https://forem.com/francgs/set-up-a-new-website-in-nginx-2o1j</link>
      <guid>https://forem.com/francgs/set-up-a-new-website-in-nginx-2o1j</guid>
      <description>&lt;h1&gt;
  
  
  Set Up a New Website in NGINX
&lt;/h1&gt;

&lt;p&gt;Run the following commands:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create the site folder&lt;br&gt;
&lt;code&gt;sudo mkdir -p /var/www/{your-domain}/&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set your user as the folder owner&lt;br&gt;
&lt;code&gt;sudo chown -R $USER:$USER /var/www/{your-domain}/&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set permissions&lt;br&gt;
&lt;code&gt;sudo chmod -R 755 /var/www/{your-domain}/&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a test &lt;code&gt;index.html&lt;/code&gt; file&lt;br&gt;
&lt;code&gt;sudo nano /var/www/{your-domain}/index.html&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;index.html&lt;/code&gt; file 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 html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Welcome to your-domain!&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Success!  The your-domain server block is working!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;For NGINX to serve this content, create a new server block with the right directives. Instead of editing the default config directly, create a new file at &lt;code&gt;/etc/nginx/sites-available/{your-domain}&lt;/code&gt;:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;sudo nano /etc/nginx/sites-available/{your-domain}&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Configuration file content:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="s"&gt;[::]:80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/var/www/your_domain&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;index&lt;/span&gt; &lt;span class="s"&gt;index.html&lt;/span&gt; &lt;span class="s"&gt;index.htm&lt;/span&gt; &lt;span class="s"&gt;index.nginx-debian.html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;your_domain&lt;/span&gt; &lt;span class="s"&gt;www.your_domain&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kn"&gt;try_files&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt;&lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;404&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;ol&gt;
&lt;li&gt;Enable the file by creating a symlink to &lt;code&gt;sites-enabled&lt;/code&gt;, which NGINX reads on startup:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;NOTE:&lt;/em&gt;&lt;/strong&gt; NGINX uses symbolic links (symlinks) to track which server blocks are enabled. Creating a symlink is like creating a shortcut: later, you can remove that shortcut from &lt;code&gt;sites-enabled&lt;/code&gt; while keeping the original config in &lt;code&gt;sites-available&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;To avoid potential hash bucket memory issues when adding additional server names, update one value in &lt;code&gt;/etc/nginx/nginx.conf&lt;/code&gt;. Open the file:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;sudo nano /etc/nginx/nginx.conf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Find the &lt;code&gt;server_names_hash_bucket_size&lt;/code&gt; directive and remove &lt;code&gt;#&lt;/code&gt; to uncomment the line. If you use &lt;code&gt;nano&lt;/code&gt;, press &lt;code&gt;CTRL + w&lt;/code&gt; to search quickly.&lt;/p&gt;

&lt;p&gt;Check for config errors: &lt;code&gt;sudo nginx -t&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Restart NGINX: &lt;code&gt;sudo systemctl restart nginx&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>linux</category>
      <category>nginx</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
