Initially, we will work on the Implementation of useForm() Hook in NextJS | React. Now In this, we work on implementation of Magento GraphQl Api’s with NextJS.
But before that we need to setup Apollo Client for managing the GraphQl Api’s.
The Apollo Client is a state management client which allow user to manage local and remote data with GraphQl and you can use it to cache, fetch, and also modify application data.
Step 1 : Install the Apollo client
Inside of your terminal run this command to install Apollo Client.
npm install @apollo/client graphql
This will add the both Apollo Client and GraphQl, which we’ll need to implement the GraphQl Query.
Step 2 : Set up the Apollo client in NextJS .
Create a file “lib/apolloClient.js” for storing the Apollo Client configuration. In which we’ll be creating a basic function that returns an Apollo Client instance.
import { useMemo } from "react"; import { ApolloClient, HttpLink, InMemoryCache } from "@apollo/client"; let apolloClient; function createApolloClient() { return new ApolloClient({ ssrMode: typeof window === "undefined", // set to true for SSR link: new HttpLink({ uri: "YOUR MAGENTO-ENDPOINTS", }), cache: new InMemoryCache(), }); }
- SSR mode true allows to prevent Apollo Client unnecessarily re-fetching of queries, Therefore we set the ssrMode should be true when page is pre-rendered using SSR (Server-Side rendering) but it needs to be false when client is rendered. for achieving this we use typeof the window object to determine uniquely that Apollo client is running on client side or server side.
- Now we’ve createApolloClient() function that returns the Apollo Client instances for given config. Apollo client will create the new instance for every page. because of that we’ll make a function initializeApollo() which calls the createApolloClient() function to create a new client in case it doesn’t exit , unless we’ll merge the Apollo cache with the initialState (initialState !== null) which is the Apollo cache value that passed in initializeApollo() function.
export function initializeApollo(initialState = null) { const _apolloClient = apolloClient ?? createApolloClient(); /* If your page has Next.js data fetching methods that use Apollo Client, the initial stategets hydrated here*/ if (initialState) { // Get existing cache, loaded during client side data fetching const existingCache = _apolloClient.extract(); /* Restore the cache using the data passed from getStaticProps/getServerSideProps combined with the existing cached data */ _apolloClient.cache.restore({ ...existingCache, ...initialState}); } // For SSG and SSR always create a new Apollo Client if (typeof window === 'undefined') return _apolloClient; // Create the Apollo Client once in the client if (!apolloClient) apolloClient = _apolloClient; return _apolloClient; }
We want Apollo client instance to be updated only when cache value is changed.
To achieve this, we going to use the useMemo() hook. We make the useApollo() function which return the memoized value of the Apollo client().
export function useApollo(initialState) { const store = useMemo(() => initializeApollo(initialState),[initialState]); return store; }
export the client for SSR use.
export const client = initializeApollo();
Step 3: Passing the Apollo Client in Apollo Provider
import { ApolloProvider } from "@apollo/client" import {useApollo} from "../lib/apollo-client" export default function App({ Component, pageProps }) { const apolloClient = useApollo(pageProps.initialApolloState); return ( <ApolloProvider client={apolloClient}> <Component {...pageProps} /> </ApolloProvider> ) }
Now overall we completed the setup of Apollo client and furthermore we going to work on GraphQl Api’s.
But Before starting to use GraphQl Api’s need to understand the basics of GraphQl for that you can visit GraphQl Api’s.
And I also provided the basic guide below:
GraphQl Query and Mutations.
For using GraphQl Api’s we must need to be understand the concept of mutations and Query.
Query : It’s used for fetching data, just like the GET method in REST API.
Mutation : It’s used for changing the data just like the POST , DELETE , and PUT method in REST API.
// Query example query Countries { country { // defining return data name code } }
// Mutation example mutation loginUser($userName: String!, $password: String!) { login(username: $userName, password: $password) { // defining return data id email firstname outlet_id lastname filename user_cart_item_list } }
Now we completed the apollo client and GraphQl basics guide, only thing which left is using implement magento GraphQl Api with our Form.
Implement the magento GraphQl Api’s with NextJS
Mutation for Create Customer Address.
In this mutation you also need to define the schema or you can say type of input values of createCustomerAddress.
For that you follow this doc or blog Schema Basic and Types
mutation Create_Customer_Address($input: Create_Customer_Input!) { createCustomerAddress(createCustomerAddressData: $input) { id region { region region_code } country_code street telephone postcode city default_shipping default_billing } }
import React, { useState, useEffect } from "react"; import { useForm } from "react-hook-form"; import Create_Customer_Address from "../api/createCustomerAddress.graphql" const LoginForm = () => { const { register, handleSubmit, formState: { errors }, reset } = useForm(); const [formData, setFormData] = useState({}); const [customerLogin, {data,error,loading] = useMutation(Create_Customer_Address); const formSubmit = (data) => { setFormData( {...data} ); customerLogin( variables: {input: formData},) }; useEffect(() => { if(data) { alert("Customer Address is successfully created") reset(); } },[loading]) return ( <form onSubmit={handleSubmit(formSubmit)}> <div className="form-container"> <label className="label">Account Information</label> <input {...register("firstName", { required: true })} placeholder="First name" /> {errors.firstName && <p className="error">First Name is required.</p>} <input {...register("lastName", { required: true, minLength: 2 })} placeholder="Last name" /> {errors.lastName && <p className="error">Last Name is required.</p>} <input {...register("company", { required: true })} placeholder="Company" /> <input type="email" {...register("email", { required: true })} placeholder="Email" /> {errors.email && <p className="error">Email address is required.</p>} <input type="tel" {...register("phone", { required: true, valueAsNumber: true })} placeholder="Phone Number" /> {errors.phone && <p className="error">Phone Number is required.</p>} <label className="label">Address</label> <input {...register("address", { required: true })} placeholder="Street Address" /> {errors.address && <p className="error">Street Address is required.</p>} <input {...register("addressL2")} placeholder="Street Address 2" /> <input {...register("addressL3")} placeholder="Street Address 3" /> {/* <input type="date" {...register("date", )} placeholder="date" /> */} <input {...register("city", { required: true })} placeholder="City" /> {errors.city && <p className="error">City name is required.</p>} <input {...register("zip", { required: true, valueAsNumber: true })} placeholder="Zip" /> {errors.zip && <p className="error">Zip Code is required.</p>} <input type="text" {...register("country", { required: true })} placeholder="Country" /> {errors.country && <p className="error">Country name is required.</p>} <input {...register("state", { required: true })} placeholder="State/Province" /> {errors.country && <p className="error">State/Province is required.</p>} </div> <div className="formData"> <input className="btn" type="submit" value="Save" /> <div className="formValues"> <p className="values">{formData.firstName}</p> <p className="values">{formData.lastName}</p> <p className="values">{formData.company}</p> <p className="values">{formData.email}</p> <p className="values">{formData.phone}</p> <p className="values"> {formData.address} {formData.addressL2} {formData.addressL3} {" "} </p> <p className="values">{formData.city}</p> <p className="values">{formData.zip}</p> <p className="values">{formData.country}</p> <p className="values">{formData.state}</p> </div> </div> </form> ); }; export default LoginForm;
Here we make the mutation of Create_Customer_Address in which we send the data of user.
And, after mutation get successfully called we called the alert() and reset the field method to indicate that user data is successfully added.
Query for get Customer Details.
In this Query we get the detail of our customer. and we going to use useQuery() hook for execute our query.
query Get_Customer_Details{ customer { firstname middlename lastname suffix prefix gender date_of_birth taxvat created_at default_shipping default_billing email is_subscribed addresses { firstname lastname street city region { region_code region } postcode vat_id country_code telephone company } } }
import React from 'react' import { useQuery } from '@apollo/client' import Get_Customer_Details from "../api/query/getCustomerDetail.graphql"; const CustomerDetails = () => { const {data, loading, error} = useQuery(Get_Customer_Details) return ( <React.Fragment> {loading ? (<h1>Loading</h1>) : ( <h1>{`${data.customer.firstname} ${data.customer.lastname}`}</h1> )} </React.Fragment> ) } export default CustomerDetails;
so this is how you Implement Magento GraphQl Api’s with NextJS,
Stay tuned for more updates.
Learn more about our Magento 2 React Development Services.
Happy Coding !!
In above example you made a query for get a customer details !! where you passed the customer_id or customer_email to fetch the details ?
Please explain