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.
nuxt-themes / alpine
The minimalist blog theme, powered by Nuxt & Markdown.
Alpine
The minimalist blog theme, powered by Nuxt.
Features
- Start from a profile page, scale to a complete blog!
- An open source blog theme powered by Nuxt Content, editable from Nuxt Studio.
- Write pages in Markdown and Vue components with the MDC syntax.
- Use 30+ built-in components in your Markdown pages.
Quick Start
npx nuxi@latest init -t themes/alpine
Contributing 🙏
- Clone this repository
- Install dependencies using
pnpm install
- Run
pnpm prepare
to generate type stubs. - Use
pnpm dev
to start playground in development mode.
License
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
Development Server
Start the development server on http://localhost:3000
npm run dev
Production
Build the application for production:
npm run build
Locally preview production build:
npm run preview
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 @koutsO 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");
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,
);
});
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]}`);
}
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;
});
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
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,
);
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();
});
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)