Pass props into <App />?

Is there any way you can do something in your server.js file and then pass the result through to the equivalent of as props? (I assume the equivalent of is your theme, so index.js inside /components)

I want to be able to access the result in my other components. I’ve tried saving it to the initial state within server.js but it’s not really what I want.

Hi @nat.clamp

The recommended way to “pass” data to React components in Frontity is through the state.

https://docs.frontity.org/learning-frontity/state

In this way:

  • It will work in both the server & client side
  • I will add reactivity to your components (if the data in the state changes the react component is re-rendered)

In Frontity there are some Lifecycle Actions that can be used to execute some logic at specific moments of Frontity bootstrap

Among these Lifecycle Actions there is one called beforeSSR that you can use to execute some logic (requests included) before Frontity starts the process of rendering the HTML from the server.

This action has access to the state so you can add things there so the data it’s avaliable to any React component you connect to the state

https://docs.frontity.org/api-reference-1/frontity#connect

Hope this helps

Hi @juanma

Thanks for your reply!
I did try putting the code into the beforeSSR action and adding the result to the state but something went wrong between there and my index.js as I get and error saying it isn’t defined.

//server.js
import { fetch } from "frontity";
import Client from 'shopify-buy';
import packageClient from "./client";

export default {
  ...packageClient,
  actions: {
    theme: {
      ...packageClient.actions.theme,
      beforeSSR: async ({ state, libraries }) => {
    const client = await Client.buildClient({
      domain: '<myshop>.myshopify.com/',
      storefrontAccessToken: '<access-token>',
    }, fetch);
    state.theme.client = { client };
  },
  }
  }
};

//index.js
    const Theme = ({ state, actions, libraries }) => {`
      useEffect(() => {
       state.theme.client.product.fetchAll().then(products => actions.theme.addShopifyProducts(products))
      }, [])

…

I get the error Uncaught TypeError: Cannot read property 'fetchAll' of undefined
Whereas if I did the exact same code but all in the index.js, it works fine. So something must be happening whilst the data is being passed over in state.

Hi @nat.clamp! :wave:

I think your problem is the following:

When you put:

const client = await Client.buildClient({
  domain: '<myshop>.myshopify.com/',
  storefrontAccessToken: '<access-token>',
}, fetch);
state.theme.client = { client };

inside of beforeSSR, this code is run on the server only. This code is adding the fetchAll() method to state.theme.client.product.

Then, Frontity serializes the state from the server and sends it to the client. The problem is that functions are not serializable in JS! So your fetchAll() will not be sent to the client from the server.

Depending on what you need I think that you will have to define the same logic on the server and on the client or just on the client or just create a custom handler

And of course any other state that you create on the server will then be present on the client (as long as it’s serializable) :slight_smile:

Hope this helps!

3 Likes

@mmczaplinski - thank you so much! This is exactly the explanation I needed. Very clear :slight_smile:

3 Likes