DEV Community

Cover image for Explorando a API do DEV.to para construir um Blog
LFXA
LFXA

Posted on • Originally published at lfxa.vercel.app

Explorando a API do DEV.to para construir um Blog

Olá, pessoal! Hoje vou compartilhar com vocês como montei uma página de blog utilizando a API do Dev.to. Esta é uma ótima forma de expandir o alcance do seu conteúdo. Além disso escrevo o mesmo post tanto em português quanto em inglês para alcançar mais pessoas e com disso existe um desafio de implementar no blog a localização para que o mesmo post funcione tanto em uma lingua quanto em outra.

Antes de falar sobre a utilização da api quero deixar três referências que me ajudaram a montar minha página de blog. Pensando na ideia de que nada se cria, apenas se combina, peguei como inspiração dois temas de blog para o Nuxt 3 e um post sobre como criar skeleton loader com tailwind CSS.

O Alpine tem um visual de posts agradável, destacando sempre o mais recente, enquanto o Nuxt Starter Blog tem uma maneira simples e eficaz de lidar com a paginação de muitos posts.

GitHub logo nuxt-themes / alpine

The minimalist blog theme, powered by Nuxt & Markdown.

Alpine

Alpine

npm version License npm downloads Nuxt Nuxt Studio Volta

The minimalist blog theme, powered by Nuxt.

Features

Quick Start

npx nuxi@latest init -t themes/alpine
Enter fullscreen mode Exit fullscreen mode

Contributing 🙏

  1. Clone this repository
  2. Install dependencies using pnpm install
  3. Run pnpm prepare to generate type stubs.
  4. Use pnpm dev to start playground in development mode.

License

MIT



GitHub logo narasimhajupally / tailwind-nuxtjs-starter-blog

This is a Nuxt.js, Tailwind CSS blogging starter template. Comes out of the box configured with the latest technologies to make technical writing a breeze. Easily configurable and customizable. Perfect as a replacement to existing Jekyll and Hugo individual blogs.

Tailwind Nextjs Starter Blog (work in progress)

Inspired by tailwind-nextjs-starter-blog

Look at the Nuxt 3 documentation to learn more.

Setup

Make sure to install the dependencies:

# npm
npm install
Enter fullscreen mode Exit fullscreen mode

Development Server

Start the development server on http://localhost:3000

npm run dev
Enter fullscreen mode Exit fullscreen mode

Production

Build the application for production:

npm run build
Enter fullscreen mode Exit fullscreen mode

Locally preview production build:

npm run preview
Enter fullscreen mode Exit fullscreen mode

Check out the deployment documentation for more information.






Gostei da ideia de juntar os dois. Assim, pude criar uma experiência única que combina o visual elegante do Alpine com a praticidade de navegação do Nuxt Starter Blog.

Thanks @kouts

O que você vai precisar:

  • A API do Dev.to, que facilita a obtenção de posts e tags para o seu blog.
  • Ferramentas como Nuxt.js e Vue-i18n para lidar com a localização do site e alternar entre os posts em diferentes idiomas.
  • Conhecimento básico de HTML, CSS e JavaScript para manipular os dados retornados pela API e criar a estrutura da sua página de blog.

Passo a passo:

Obtenha os posts e tags da API do Dev.to:

Utilizei a API para recuperar os posts escritos por você e as tags associadas a cada post. Usei meu nome de usuário como parâmetro de consulta para essa chamada, juntamente com o estado "all", garantindo que a resposta retorne no máximo 1000 posts com as tags associadas, em vez dos 30 padrão. (espero escrever pelo menos 500 posts 😅)

    const { data: posts, pending } = await useFetch(
        "https://dev.to/api/articles?username=lfxa&state=all");
Enter fullscreen mode Exit fullscreen mode

Trabalhe com a localização do site e manipule os dados retornados pela API:

Agora vem a parte interessante: para tornar isso funcional, é necessário ter o post disponível tanto em inglês quanto em português no dev.to. Para determinar se o post está em uma das línguas, utilizo o campo "canonical_url" com a localização na URL (por exemplo: https://lfxa.vercel.app/en-US/blog?to=um-portfolio-de-um-engenheiro-de-software-162o,a-portfolio-of-a-software-engineer-3i47). Este campo indica a URL de onde o post foi originalmente publicado e é redirecionado para o meu site. Aplico um filtro para exibir apenas os posts na localização desejada.

    const route = useRoute();
    const { locale } = useI18n();

    const filteredBlogPosts = computed(() => {
      return props.posts
        ?.filter((post) => {
            // localização na url
          const postLang = post.canonical_url.split("/")[3];      
          const isSameLanguage = postLang === locale.value;

          //filtrar tag e localização
          const hasTagQuery = route.query.tag !== undefined;
          return isSameLanguage &&
               (!hasTagQuery || post.tag_list.includes(route.query.tag));
        })
        // paginação
        .slice(
          props.postPerPage * (currentPage.value - 1),
          currentPage.value * props.postPerPage,
        );
    });
Enter fullscreen mode Exit fullscreen mode

Como o post foi originalmente publicado no dev.to, faço um redirecionamento caso alguém clique no link que leva diretamente ao meu site. (precisa ser melhorado caso adicione mais localizações ao site 😉).

    // redirecionar para o post em determinada localização
    if (route.query.to !== undefined) {
      const toPost = route.query.to.split(",");
      const index = locale.value === "pt-BR" ? 0 : 1;
      await navigateTo(`/blog/${toPost[index]}`);
    }
Enter fullscreen mode Exit fullscreen mode

Filtrei as tags para que apareçam em sua determinada localização:

    const tags = computed(() => {
      const tagCounts = {};
      props.posts?.forEach((post) => {
        const lang = post.canonical_url.split("/")[3];
        post.tag_list.forEach((tag) => {
          const key = tag + ":" + lang;
          if (tagCounts[key]) {
            tagCounts[key]++;
          } else {
            tagCounts[key] = 1;
          }
        });
      });

      const output = [];
      for (const tagLang in tagCounts) {
        const key = tagLang.split(":");
        output.push({ name: key[0], quantity: tagCounts[tagLang], lang: key[1] });
      }
      output.sort((a, b) => a.name.localeCompare(b.name));
      return output;
    });    
Enter fullscreen mode Exit fullscreen mode

e adicionei também um filtro para as tags que são selecionadas e se tornam parâmetros de consulta:

    // v-if
    tag.lang === $i18n.locale;

    // nuxtLink to
    route.fullPath.includes(tag.name) ? 'blog' : 'blog?tag=' + tag.name
Enter fullscreen mode Exit fullscreen mode

Crie a estrutura da página de post blog:

Para obter o conteúdo do post, é necessário fazer uma consulta à API específica para aquele determinado post. Utilizei o slug do post juntamente com o meu nome de usuário como parâmetros de consulta na API. O conteúdo do post é fornecido no campo "body_html", mantendo as classes CSS do site do dev.to. Para garantir uma visualização adequada do post, copiei parte do CSS do site que faz sentido. Recomendo evitar o uso da diretiva v-html, pois é sensível a ataques XSS (Cross-Site Scripting). (Espero que o dev.to não transmita scripts maliciosos que possam ser executados nos sites dos usuários).

       const { data: post, pending } = await useFetch(
      "https://dev.to/api/articles/lfxa/" + slug,
    );
Enter fullscreen mode Exit fullscreen mode

Além disso, caso haja uma alteração de idioma na página, faço uma nova chamada para o mesmo post na outra língua:

    onBeforeRouteLeave(async (to, from, next) => {
      if (
        post.value &&
        to.fullPath.split("/").pop() === from.fullPath.split("/").pop()
      ) {
        const last = post.value.canonical_url.split("/").pop();
        const toPost = last.replace("blog?to=", "").split(",");
        const index = locale.value === "pt-BR" ? 0 : 1;
        await next(`/${locale.value}/blog/${toPost[index]}`);
      }
      next();
    });
Enter fullscreen mode Exit fullscreen mode

Caso seja do seu interesse, pode ver o código fonte no github aqui.


Conclusão:

Compartilhar o que sabemos é essencial para tornar o aprendizado mais acessível e promover o crescimento de outros desenvolvedores. Além disso, ao compartilhar conhecimento, fortalecemos nossas próprias habilidades, vemos o que pode ser melhorado e contribuímos para o avanço da comunidade de desenvolvimento de software em geral.

Assim brilhe a luz de vocês diante dos homens, para que vejam as suas boas obras e glorifiquem ao Pai de vocês, que está nos céus. Mateus 5:16

Top comments (0)