O desafio do SEO para SPAs com CSR: Extraindo o melhor para Indexação
Tags: vue, seo, frontend, braziliandevs
Published: 2023-06-25 21:04:25

No atual cenário do desenvolvimento web, as decisões sobre tecnologia e arquitetura de um site podem ter implicações profundas, que podem revelar desafios inesperados.

Imagine ter desenvolvido uma Single Page Application (SPA) com renderização do lado do cliente (CSR). Contudo, um detalhe crucial foi esquecido - a otimização para mecanismos de busca. 

Agora surge a pergunta: descartar todo o projeto porque essa não é a arquitetura mais otimizada para SEO? Nem sempre essa é uma opção viável no momento, e precisamos encontrar a melhor solução para o problema. Nesse contexto, este artigo explora estratégias que podemos adotar para assegurar que um site alcance a melhor indexação possível, sem a necessidade de uma transformação completa em um Server Side Rendering (SSR), que poderia acarretar em aumentos consideráveis nos custos e prazos de entrega. 

Vale destacar que, na maioria dos casos, a renderização mais apropriada para SEO é o SSR. Contudo, se você se deparou com um problema semelhante ao mencionado acima, este artigo oferecerá soluções que podem te ajudar.

---


## O problema do CSR para o SEO

Ao adotar um framework de maneira convencional, como o Vue.js, cria-se uma Single Page Application (SPA) com renderização do tipo Client Side Rendering "CSR". Nesse método, a renderização ocorre no lado do navegador do cliente, em que inicialmente o servidor envia um documento HTML básico com uma única div vazia, acompanhado dos arquivos JavaScript e posteriormente, o navegador executa esses scripts para buscar e renderizar todo o conteúdo do site.

O impacto mais significativo nos motores de busca ocorre devido a esse processamento extenso, resultando na complexidade para os bots interpretarem todo o conteúdo gerado por JavaScript. Isso não significa que o rastreamento é ignorado, pelo contrário, ele ocorre em duas etapas:
- Primeiro o rastreamento inicial varre o HTML e identifica recursos JavaScript, 
- Em seguida ocorre o processamento para a renderização.

Em contrapartida, ao utilizar uma renderização do tipo Server Side Rendering "SSR", o servidor envia inicialmente um HTML com todo o conteúdo já pronto. Isso aumenta a precisão da indexação pelos bots de pesquisa. Apesar de potencialmente mais lenta para carregamentos iniciais de páginas, dependendo da quantidade de conteúdo, essa estratégia facilita a interpretação do conteúdo pelos motores de busca.

Outro desafio do CSR reside no processo mais demorado de adicionar tags meta com conteúdo dinâmico. Isso ocorre porque somente as APIs conhecem o conteúdo e são requisitadas quando os arquivos JavaScript são executados. Esse procedimento pode demandar mais tempo se comparado ao mesmo processo em um SSR, onde as meta tags já estão incorporadas ao HTML no momento do carregamento.


## Extraindo o melhor para indexação

Na busca pela otimização do SEO em uma SPA CSR, fontes confiáveis, como os artigos e vídeos do Google mencionados nas referências, oferecem insights aprofundados sobre estratégias para aprimorar a indexação do seu site. 

Um dos primeiros aspectos a se atentar é o problema das técnicas de cloaking, onde mudanças drásticas de conteúdo em um site, como estar falando sobre carros e em outra página mostrar dicas para alimentação de cachorros, podem resultar em penalizações no SEO. Para evitar isso, é crucial que uma SPA tenha um tema principal comum entre todas as páginas.


### Preparando o back end

Se o conteúdo estiver apto, vamos ao que precisa ser feito no lado do backend. Para garantir as meta tags personalizadas de acordo com o conteúdo da página, será preciso preparar um endpoint GET de API, que ao ser requisitado com um query param contendo a página deseja, retorne todos os dados necessários para adicionar tags title e meta descriptions. Dessa forma deixamos tudo mais flexível e o backend que conhece o conteúdo é que dirá quais tags de SEO usar.

É preciso garantir que a API esteja configurada adequadamente, sendo capaz de responder a cenários de erro com o status code correspondente. Por exemplo, o servidor deve retornar um estado de código de erro 404 quando a URL acessada for `/not-found` e 500 quando acessar `/maintenance`.


### Preparando o front end

Para o front end apresentarei estratégias com o framework Vue, mas vale ressaltar que podem ser adaptadas para outras tecnologias. 

As tags meta devem ser uma das primeiras partes a serem adicionadas ao site. Para alcançar isso, podemos fazer uso do Vue-router, com um hook que é executado antes de cada rota. Esse hook será o responsável por adicionar todas as meta tags no HTML, aproveitando os dados de SEO prontos obtidos ao requisitar o endpoint GET da API, conforme exemplificado no código abaixo.

```ts
// Exemplo de código para adição de meta tags com o Vue-router

/**
 * Remove todas meta tags do head do html.
 */
export const removeAllMetaTags = (): void => {
    const { head } = document;

    const metaTags = head.getElementsByTagName('meta') as HTMLCollectionOf<HTMLMetaElement>;

    if (!metaTags) return;

    Array.from(metaTags).forEach((metaTag) => {
        head.removeChild(metaTag);
    });
};

type MetaNames = 'description' | 'keywords' | 'og:title' | 'og:description' | 'og:image' | 'addsearch-custom-field';

export interface RouteMetaTags {
    name?: MetaNames;
    content: string;
    property?: string;
    'data-type'?: string;
}

/**
 * Adicione as novas meta-tags com os atributos correspondentes a rotas que possuem metaTags
 * @param to - a rota que está sendo acessada
 */
export const addMetaTagsAndTitleByRoute = async (to: RouteLocationNormalized) => {
	// Inserir abaixo a requisição passando o nome da rota
	const { data } = await axios.get(`apiurl/seo?route=${to.name}`);

    document.title = data.meta.title;

    if (data.meta.metaTags) {
        data.meta.metaTags.forEach((tag: RouteMetaTags) => {
            const metaTag = document.createElement('meta');

            Object.entries(tag).forEach(([key, value]) => {
                metaTag.setAttribute(key, value as string);
            });

            document.head.appendChild(metaTag);
        });
    }
};

/**
 * Antes de cada rota ser renderizada, atualiza as meta-tags de acordo com a rota acessada
 */
router.beforeEach(async (to, from, next) => {
    removeAllMetaTags();

    await addMetaTagsAndTitleByRoute(to);

    next();
});
```

Além disso, alguns cuidados adicionais no código front-end são cruciais para evitar problemas, como:
- Garantir URLs diferentes para cada página;
- Utilizar redirecionamento JavaScript para URLs que o servidor responda com um código de status HTTP 404, como `/not-found`.
- Adicionar a tag `<meta name="robots" content="noindex">` às páginas de erro.
- Preferir o uso da API History em vez de fragmentos `#` nas URLS.

Outros cuidados recomendados estão detalhados nos sites referenciados neste artigo. É altamente aconselhável a leitura desses recursos para implementar as ações necessárias e garantir o melhor desempenho possível.


## Conclusão

Ao longo deste artigo, exploramos os desafios enfrentados ao otimizar a indexação de Single Page Applications (SPAs) com Client-Side Rendering (CSR) para mecanismos de busca. Trouxe uma série de estratégias e soluções para superar as limitações dessa arquitetura, reconhecendo, no entanto, que não é a melhor forma de otimizar o SEO de um site.

O propósito deste artigo vai além de oferecer uma solução, é um convite à comunidade para questionar, inovar e colaborar na busca de soluções mais eficientes. Espero inspirar você leitor a experimentar e compartilhar suas descobertas.

Você já enfrentou desafios semelhantes em SEO para SPAs com CSR? Se sim, adoraria ouvir sobre suas experiências e soluções. 


---

### Referências

Artigos do Google que você precisa ler:
- https://developers.google.com/search/docs/crawling-indexing/javascript/javascript-seo-basics?hl=pt-br
- https://developers.google.com/search/docs/crawling-indexing/javascript/dynamic-rendering?hl=pt-br
- https://web.dev/articles/rendering-on-the-web?hl=pt-br#combining_server-side_rendering_and_client-side_rendering_via_rehydration

Vídeos:
- https://www.youtube.com/watch?v=l-JWN2x_Na0
- https://www.youtube.com/watch?v=Op8Q8bUAKNc


---


**Gosta de desenvolvimento web? Então faça parte dessa comunidade no Youtube:** https://www.youtube.com/@merielimanzano

| 📃 Outros artigos que você pode gostar |
|                    -----               |
| [Produtividade com Testes e Vue usando VSCode](https://dev.to/merielimanzano/produtividade-com-testes-e-vue-usando-vscode-593k) |