Server side rendering (SSR) for components in Store Framework

[EN]
Hello everybody.
I need help with a question: how to perform server-side component rendering (SSR)?

I need to print the information coming from GraphQL before rendering the component, hence the need for SSR.
I tried several ways but none met the need.
I’m using useQuery, from react-apollo.

I’ve tried to declare “render” as “server” in interfaces.json, but without success. I tried to create a hook with query but without success too.

The useState and useLayoutState don’t work either, as the information stays as “undefined” until the query returns.

The use of the rest api would even work, but it would have to be through the SSR as well, since react “does not wait” for requests.

[PT]
Olá a todos.
Preciso de ajuda com uma questão: como realizar a renderização do componente no lado do servidor (SSR)?

Preciso imprimir as informações que veem do GraphQL antes da renderização do componente, por isso a necessidade do SSR.
Tentei de diversas formas mas nenhuma atendeu a necessidade.
Estou usando o useQuery, do react-apollo.

Já tentei declarar o “render” como “server” nas interfaces, mas sem sucesso. Tentei criar um hook para ver se ele trazia as informações e sem sucesso também.

O useState e useLayoutState não atendem também, já que a informação fica como “undefined” até que o retorno da consulta seja concluído.

O uso da rest api até atenderia, mas teria que ser pelo SSR também, já que o react “não espera” as requisições.

1 Like

Hi @alexm4tos
While using useQuery or any other method you have the option to enable/disable SSR, there are components in render-runtime to wrap your react app with, can you explain a little or provide more detail to the code?

Regards

1 Like

Hi @TanishqxSharma

I’m in need of this feature to add some SEO functionality. Below is the code we used. Note that it has useEffect, but as I mentioned in the previous topic, it doesn’t work as expected.

// ProductCollectionSchema.tsx

import React, { useEffect, useState } from 'react';
import { Helmet, useRuntime } from 'vtex.render-runtime';
import { useQuery } from 'react-apollo';

import QUERY_CATEGORY from '../../../graphql/queries/getCategory.graphql';

interface Category {
	id: string;
	name: string;
	title: string;
	description: string;
	linkId: string;
}

const ProductCollectionSchema: StorefrontFunctionComponent = () => {
	const [category, setCategory] = useState<Category>();
	const runtime = useRuntime();

	const fetchCategory = useQuery(QUERY_CATEGORY, {
		variables: {
			id: runtime.route.params.id,
		},
	});

        useEffect(() => {
		if (fetchCategory.data === undefined) {
			fetchCategory.refetch();
		} else {
			setCategory(fetchCategory.data.category);
		}
	}, [fetchCategory]);

        const contextSchema = {
                '@type': 'CollectionPage',
                ...
                name: `${category?.name}`,
                description: `${category?.description}`
        }

        const jsonLd = JSON.stringify(contextSchema);

        return (
		<>
			<Helmet>
				<script type='application/ld+json'>{jsonLd}</script>
			</Helmet>
		</>
	);
};

export default ProductCollectionSchema;
// getCategory.graphql

query getCategory($id: ID!) {
  category(id: $id) {
    id
    name
    title
    description
    linkId
  }
}

In the source code (CTRL + U) it looks like this.

image

In devtool, after page load, it looks as expected.

image

1 Like

Can you try using this if this doesn’t work

const fetchCategory = useQuery(QUERY_CATEGORY, {
		variables: {
			id: runtime.route.params.id,
		},
            ssr:false
	});

Can you also try this? and let me know if this works

const [fetchData,{loading,data,error}] = useLazyQuery(QUERY_CATEGORY, {
		variables: {
			id: runtime.route.params.id,
		},
            ssr:false
	});

useEffect(()=>{
fetchData();
},[])

1 Like

@TanishqxSharma I tested with these codes you sent, but without success. I also tried using “true” for the SSR but it’s still the same.
In all cases the initial value is undefined and after it has the correct value, but unfortunately it doesn’t go to the source code (which is necessary for SEO).

1 Like

I’ll have to dive deeper into this, my initial reaction to your question is that stores running on Store Framework are CSR-only. We are building FastStore (currently in Closed Beta) to allow developers to achieve better performance building stores in React using Gatsby and Next.js.

But are you sure you need SSR for your application? Could you share your specific SEO challenge? Check this out: Is React client side SEO friendly or not?

@georgebrindeiro I believe that SSR is the only way to get the data I need so that it can be used to render the JSON in compliance with the structured data.
Initially, there are two challenges, both related to SEO: the first is to create a JSON (following schema.org specifications) that tells search engines what the page really is and the actions that can be taken from it. For this the creation of the CollectionPage schema.

The second is the availability of review information for each product, in order to increase the conversion of search clicks. As a third-party resource is used (YourViews Reviews) it is necessary to retrieve the data through GraphQL, hence the need for SSR.

If the information were retrieved by the client, it would not be seen by search engines due to the way they read this data.