How to use app bridge with my own redux store?

Hello,

I’ve setup my shopify app by following build a shopify app with node and react tutorial.

Currently my _app.js file is;

import App from 'next/app';
import Head from 'next/head';
import { AppProvider } from '@shopify/polaris';
import { Provider } from '@shopify/app-bridge-react';
import '@shopify/polaris/dist/styles.css';
import translations from '@shopify/polaris/locales/en.json';
import Cookies from 'js-cookie';
import ClientRouter from '../components/ClientRouter';
import ApolloClient from 'apollo-boost';
import { ApolloProvider } from 'react-apollo';

const client = new ApolloClient({
    fetchOptions: {
        credentials: 'include'
    },
});

class MyApp extends App {
    render() {
        const { Component, pageProps } = this.props;
        const config = { apiKey: API_KEY, shopOrigin: Cookies.get("shopOrigin"), forceRedirect: true };
        return (
            
        );
    }
}

export default MyApp;

The problem is I don’t know exactly how can i create my own redux store for my own components (not the ones mentioned here app bridge actions) and as well as how can i attach my react-redux Provider component to that store while still relying on app bridge?

Which Provider should cover other → app-bridge-react Provider or react-redux Provider ?

I believe i should somehow create my own actions for my custom components and should be able to dispatch them through my own part of redux store just like pre-defined actions in app bridge.

I’ve been looking for this answer for almost a decade but unfortunately I was not able to find any proper example on the web nor under the shopify app developments tutorials.

Could you please help me on this ?

Thanks,

Hi barisozdogan,

You should be able to use Redux without any affect on App Bridge. Although App Bridge stores its state in a Redux store, this is handled in Shopify Admin.

Which Provider should cover other → app-bridge-react Provider or react-redux Provider ?

It doesn’t matter which Provider covers the other. App Bridge components will work as long as the App Bridge Provider exists somewhere as a parent.

Hope this helps!

Trish

EDIT: Nevermind! I was looking at the wrong redux-store in my redux dev tools!

Hi Bari,

How were you able to solve your situation?

My code:

import React from "react";
import App from "next/app";
import Head from "next/head";
import { AppProvider } from "@shopify/polaris";
import { Provider, Context } from "@shopify/app-bridge-react";
import { authenticatedFetch } from "@shopify/app-bridge-utils";
import "@shopify/polaris/dist/styles.css";
import "../css/main.css";
import translations from "@shopify/polaris/locales/en.json";
import ApolloClient from "apollo-boost";
import { ApolloProvider } from "react-apollo";
import { Provider as ReduxProvider } from "react-redux";
import { store } from "../store";

function userLoggedInFetch(app) {
    const fetchFunction = authenticatedFetch(app);

    return async (uri, options) => {
        console.log("URI", uri);
        const response = await fetchFunction(uri, options);

        if (
            response.headers.get(
                "X-Shopify-API-Request-Failure-Reauthorize"
            ) === "1"
        ) {
            const authUrlHeader = response.headers.get(
                "X-Shopify-API-Request-Failure-Reauthorize-Url"
            );

            const redirect = Redirect.create(app);
            redirect.dispatch(Redirect.Action.APP, authUrlHeader || `/auth`);
            return null;
        }

        return response;
    };
}

class MyProvider extends React.Component {
    static contextType = Context;

    render() {
        const app = this.context;

        const client = new ApolloClient({
            // fetch: authenticatedFetch(app),

            fetch: userLoggedInFetch(app),
            fetchOptions: {
                credentials: "include",
            },
        });

        return (
            
        );
    }
}

class MyApp extends App {
    render() {
        const { Component, pageProps, shopOrigin } = this.props;
        const config = { apiKey: API_KEY, shopOrigin, forceRedirect: true };
        return (
            
        );
    }
}

MyApp.getInitialProps = async ({ ctx }) => {
    return {
        shopOrigin: ctx.query.shop,
        API_KEY: process.env.SHOPIFY_API_KEY,
        host: process.env.SHOPIFY_APP_URL,
    };
};

export default MyApp;
import { createStore, applyMiddleware, combineReducers } from "redux";
import { shopifyReducer } from "./shopify/reducers";
import { cartUIReducer } from "./cartUI/reducers";
import { variantsReducer } from "./variants/reducers";
import { composeWithDevTools } from "redux-devtools-extension";
import reduxThunk from "redux-thunk";
const rootReducer = combineReducers({
    shopify: shopifyReducer,
    cartUI: cartUIReducer,
    variants: variantsReducer,
});

export type RootState = ReturnType