coding

Eu pago R$0,00 em hospedagem para esse site

Escrito em 17 de abril de 2021 - 🕒 11 min. de leitura

Quando eu estava na faculdade, web development não era uma parte importante da programação como é hoje, eu não tive uma única aula sobre web e agora trabalho com isso todos os dias. Quem diria.

Eu lembro que aprendi um pouco de HTML na escola, por volta de 1999, e ficava fazendo sites incríveis tipo o gif abaixo:

My website

The old ways

Antigamente (na época do Dreamweaver), se eu quisesse fazer um site, eu teria algo assim:

- website
  - index.html
  - about.html
  - contact.html

E aí para cada um desses arquivos, eu teria que escrever o HTML completo para aquela página, mesmo se todas elas tivessem o mesmo header ou logo etc. Neste exemplo não há banco de dados, dados dinâmicos e nem compilação, o site é 100% estático, eu posso simplesmente abrir esses arquivos no meu browser localmente e tudo funcionará sem a necessidade de servidores, porque HTML é praticamente um texto com esteróides.

Claro que isso está longe de ser o ideal, então outras soluções como o PHP surgiram com a possibilidade de deixar as coisas mais dinâmicas.

Not that old ways

Com o PHP, eu posso dividir o meu template de HTML em pedaços reutilizáveis, então eu poderia facilmente inicializar um framework tipo WordPress e me concentrar apenas na criação do conteúdo do site.

O problema é que o meu browser não entende PHP, então eu preciso de um servidor para converter toda a lógica do PHP em HTML estático, então toda a vez que alguém faz uma solicitação para ver uma página no meu site, a solicitação vai para o meu servidor, que vai processar o código PHP e servir uma página HTML e, claro, isso custa muito mais do que simplesmente servir arquivos HTML estáticos.

Uma estrutura de arquivos de um site em PHP seria algo assim:

- website
      - index.php
      - header.php
      - footer.php
  - content
      - home.php
      - about.php
      - contact.php

É aqui que se encontra a maior parte dos sites agora, e por um bom motivo, a Web 2.0 é complexa e toda esse dinamismo é necessário… pelo menos na maioria dos casos, mas e os sites que quase não mudam, como blogs ou portfólios?

The new way - JAMStack

JAMStack significa JavaScript, API & Markup - Stack e está aqui para trazer o melhor dos velhos tempos para nossas vidas. Com JAMStack eu posso criar meu site da mesma forma que faria usando PHP, mas em vez de ter os dados processados em cada solicitação, eu posso programar o meu site inteiro em módulos, pré-compilá-lo apenas uma vez e depois servi-lo como HTML estático + JavaScript. Isso é muito útil para sites como este, e essa técnica não é nova, todos os nossos aplicativos de desktop são pré-compilados e servidos “estaticamente” - vamos esquecer o SaaS por um segundo, ok?

Por exemplo, neste site eu tenho um template para uma página de posts do blog e eu preencho esse template com dados vindo de um arquivo Markdown, a estrutura do projeto é algo tipo:

- website
      - index.html
  - pages
      - home.html
      - contact.html
  - templates
      - blog-posts.html
  - content
      - my-first-post.md
      - my-second-post.md

Eu estou usando o Gatsby para fazer esse site, então posso escrever tudo usando componentes React, e o Gatsby compila tudo em um monte de arquivos HTML que são servidos ao navegador.

Por onde começar?

Antes de testar o Gatsby, eu comecei com o Jekyll, que é uma forma de criar um blog JAMStack e hospeda-lo gratuitamente no GitHub Pages, era tudo que eu precisava, mas primeiro tive que converter todos os meus 12 anos de posts no WordPress em arquivos Markdown com frontmatter.

Os posts do WordPress são (geralmente) armazenados em um banco de dados, então preciso extrair esses dados e salvá-los como um arquivo Markdown, e a maneira mais fácil de fazer isso é simplesmente usar um plugin do WordPress, como o wordpress-to-jekyll-exporter. Se você não tem mais acesso ao seu blog, mas ainda tem o arquivo database.sql (como eu 😅) apenas inicialize uma versão local do WordPress para exportar seus posts.

Eu também criei um script em Python para alterar alguns dados dos arquivos Markdown gerados para atender algumas das minhas necessidades.

Eu tinha mais de 100 posts no meu blog, então foi uma surpresa para mim, descobrir que não tinha como usar o plugin de paginação v2 do Jekyll e fazer o deploy automaticamente no GitHub Pages, então decidi procurar outras soluções.

O Grande Gatsby

Como eu já conheço bem React, usar o Gatsby é praticamente um no-brainer, e eles têm uma excelente documentação e muitos plugins e tutoriais e com o lançamento do GitHub Actions, é possível fazer o build e deploy do Gatsby no próprio GitHub sem precisar de serviços externos como travis-ci.org. Não só isso, mas eu poderia até mesmo ter meu código em um repositório privado e fazer o deploy em outro repositório público, dessa forma eu posso ter posts que são rascunho e que não quero que fiquem públicos.

Primeiro eu fiz este repositório com base nas instruções deste repositório do Material UI. Tudo o que ele faz é vincular a biblioteca Material UI React ao Gatsby.

A próxima etapa foi pegar o gatsby-material-ui-starter como base para adicionar toda a lógica do meu blog, mas primeiro eu precisava de uma lista de todos os recursos que eu queria que o meu blog tivesse, e esses eram:

  • Página inicial com lista de posts
  • Página de blog com lista de posts
  • Página de posts do blog com posts relacionados
  • Página de arquivo com paginação
  • Comentários
  • Página de contato
  • Página de álbuns com fotos do Google Photos
  • Caixa de busca
  • SEM SERVIDORES

Tudo parece bastante razoável até que você lembrar que tudo isso precisa ser feito com JAMStack e sem servidores. Isso é mesmo possível? SIM. Gatsby e React são ferramentas realmente poderosas.

Lista de posts e posts relacionados

O Gatsby fornece uma API de GraphQL bem simples para obter dados dos arquivos Markdown, e isso pode ser feito facilmente usando o plugin gatsby-transformer-remark e uma query de GraphQL como a abaixo:

export const pageQuery = graphql`
    query Posts($locale: String) {
        allMarkdownRemark(
            filter: {
                fields: { locale: { eq: $locale } }
                frontmatter: { show: { eq: true } }
            }
            sort: { fields: [frontmatter___date], order: DESC }
        ) {
            edges {
                node {
                    excerpt
                    fields {
                        slug
                        path
                        locale
                    }
                    frontmatter {
                        date
                        title
                    }
                }
            }
        }
    }
`;

Se você quiser saber mais sobre como criar seu próprio blog com o Gatsby do zero, siga o tutorial oficial.

Para os posts relacionados, decidi pegar todos os meus posts e verificar em cada um deles quais outros posts tem as mesmas tags, e então ordena-los por quantidade de tags iguais. Esta pode não ser a maneira eficiente de fazer isso, mas lembre-se de que só estou compilando o site uma vez, então tudo bem 😊

Paginação

O Material UI já tem um componente de paginação, então eu criei um template Archive.jsx que recebe uma lista de posts, um número total de páginas e o número da página atual e durante o processo de compilação de Gatsby, eu crio várias páginas de arquivo usando o meu template e é isso. Fácil demais.

Busca

Já que o Gatsby usa tecnologias de JavaScript ultra-modernas, criar uma pesquisa local deve ser muito fácil, certo? SIM! Existe até um plugin para isso já! Show!

Basta seguir esse tutorial e combinar o código com o componente de autocomplete do Material UI para criar um componente SearchBar igual ao desse blog.

Integração com Google Photos

A parte ruim do JAMStack é que meu repositório git conterá não apenas todo o meu código-fonte, mas também todos os meus dados de conteúdo, incluindo fotos, etc, e isso acaba deixando o meu repositório muito grande.

Claro que eu poderia consumir meus dados via uma API externa em vez de arquivos Markdown e isso já vai ajudar um pouco, mas poder não armazenar fotos no repositório vai economizar muito espaço.

Graças a este belo post feita pelo @ValentinHervieu podemos ter uma ideia de como obter a URL das imagens de um álbum do Google Photos, eu posso simplesmente seguir esse post e adicionar o código no meu processo de build do Gatsby.

Multi-línguas

Bom como português é a minha língua nativa, e eu moro fora do Brasil, é útil poder escrever posts em múltiplos idiomas para poder compartilhar com meus amigos aqui e no Brasil, e para isso eu preciso adicionar uma funcionalidade de poder criar posts em línguas diferentes, e óbviamente existe um plugin do Gatsby para isso.

Esse plugin é baseado no famoso React Intl, e é bem simples de usar, basta adicionar um novo objeto nas configurações de plugin do Gatsby a passar uma array com os códigos das línguas que você quer adicionar e um path para onde ficarão as traduções para essas línguas. Veja abaixo como é esse objeto para esse blog:

module.exports = {
    ...config,
    plugins: [{
        resolve: 'gatsby-plugin-intl',
        options: {
            path: `${__dirname}/src/intl`,
            languages: ['en', 'pt-br'],
            defaultLanguage: 'en',
            redirect: true,
            redirectComponent: require.resolve('./src/utils/redirect.js'),
        },
    }],
};

O que isso fará é que sempre que você criar uma página tipo /contact/, ele criará uma página para cada um dos idiomas para os quais você configurou, tipo /en/contact/ e /pt-br/contact/. Maneiro! Mas, e os posts do blog? Não quero paths tipo /en/hello-world/ e /pt-br/hello-world/, eu quero /en/hello-world/ e /pt-br/ola-mundo/.

Para ter o mesmo post em diferentes idiomas, eu crio arquivos de markdown tipo hello-world.en.md e hello-world.pt-br.md e, em seguida, conecto eles pelo título e a data do post, dessa forma é possível mudar o idioma na página do post e ver o mesmo post em outro idioma.

Language switcher

Página de contato e sistema de comentários

Existem alguns serviços que oferecem sistemas de comentários para o seu site, como disqus.com e o Facebook Comments, mas o plano gratuito do Disqus adicionará anúncios ao seu site, e o Facebook exigirá que os usuários tenham uma conta no Facebook para usá-lo.

Depois de um tempo pesquisando eu descobri ser possível usar o Google Forms como um sistema de comentários para o meu blog em JAMStack.

Os dados dos comentários são armazenados em uma planilha do Google no seu Google Drive, que pode então ser acessada no processo de build do Gatsby para passar todos os comentários para os devidos posts do blog.

Um problema de usar este sistema é que se eu quiser que os novos comentários apareçam no blog, eu preciso buildar o site todo novamente, mas vamos pensar nisso como um processo para aprovar / desaprovar comentários 😄 e também se você configurar o Gatsby direitinho, fazer re-builds não é um grande problema.

GitHub Actions

Após programar tudo isso (incluindo algumas gambiarras), tudo o que resta é usar GitHub Actions para fazer o build e o deploy do meu site, e para isso eu simplesmente crio um arquivo .github/workflows/deploy.yml no meu repositório do GitHub com as seguintes configurações:

name: Deploy to GitHub Pages
on:
  workflow_dispatch:
  push:
    branches:
      - main

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/[email protected]
        with:
          persist-credentials: false

      - name: Install and Build 🚧
        run: |
          npm cache clean --force
          npm install
          npm run clean
          npm run build

      - name: Deploy 🚀
        uses: JamesIves/github-pages-deploy-[email protected]
        with:
          token: ${{ secrets.ACCESS_TOKEN }}
          repository-name: blopa/pablo.gg
          branch: gh-pages
          folder: public
          clean: true
          single-commit: true

Isso irá buildar o site toda vez que eu commitar no branch main e depois fará o deploy no meu repositório público github.com/blopa/pablo.gg para que possa ser acessado via https://pablo.gg/.

Por quê?

Você pode estar se perguntando “por que você simplesmente não pega um servidor de R$5,00 por mes e roda um WordPress nele?”, e eu digo por que, não é apenas uma questão de economizar dinheiro, mas também é uma coisa a menos com que se preocupar, e se eu morrer ou entrar em coma sei la, meu site ainda estará online - desde que o GitHub Pages ainda exista e seja gratuito. E ao usar o JAMStack você automaticamente diminuirá o poder de processamento usado para servir o seu site, o que também diminuirá as emissões de CO2 e salvará o planeta (ou pelo menos ajudará um pouquinho).

Conclusão

Eu não só aprendi um novo framework em React, mas também criei um blog pessoal ultra leve com custo de hospedagem de R$0,00, e mesmo que o GitHub Actions ou o GitHub Pages deixe de existir um dia, eu posso simplesmente buildar o meu blog localmente e depois hospeda-lo em algum servidor de arquivos estáticos e isso me custaria muito pouco por ano, então yay!

Claro que eu acabo pagando pelo domínio .gg, mas se você quiser ir full frugal, você pode simplesmente hospedar o seu site usando domínios gratuitos como o github.io ou o freenom.com.

Tags:


Publicar um comentário

Comentários

Nenhum comentário.