docs: resolved occurrences of gatsby storefront (#3754)
This commit is contained in:
@@ -144,170 +144,6 @@ Now, if you run your Medusa backend and your storefront, on checkout you’ll be
|
||||
|
||||
You can test out the payment with PayPal using your sandbox account.
|
||||
|
||||
### Add to Gatsby Storefront
|
||||
|
||||
:::note
|
||||
|
||||
Medusa's Gatsby storefront is deprecated and it is recommended to use the [Next.js storefront](../../starters/nextjs-medusa-starter.mdx) or build your own storefront instead.
|
||||
|
||||
:::
|
||||
|
||||
In your `.env.development` file (or the file you’re using for your environment variables) add the following variable with its value set to the Client ID:
|
||||
|
||||
```bash title=.env.development
|
||||
GATSBY_PAYPAL_CLIENT_ID=<CLIENT_ID>
|
||||
```
|
||||
|
||||
Then, install [PayPal’s React components](https://www.npmjs.com/package/@paypal/react-paypal-js) library:
|
||||
|
||||
```bash npm2yarn
|
||||
npm install @paypal/react-paypal-js
|
||||
```
|
||||
|
||||
Next, create a new file `src/components/payment/paypal-payment/index.jsx` with the following content:
|
||||
|
||||
```jsx title=src/components/payment/paypal-payment/index.jsx
|
||||
import {
|
||||
PayPalButtons,
|
||||
PayPalScriptProcessor,
|
||||
} from "@paypal/react-paypal-js"
|
||||
import React, { useMemo, useState } from "react"
|
||||
|
||||
import { navigate } from "gatsby"
|
||||
import { useCart } from "../../../hooks/use-cart"
|
||||
import { useMedusa } from "../../../hooks/use-medusa"
|
||||
|
||||
const paypalClientId = process.env.GATSBY_PAYPAL_CLIENT_ID || ""
|
||||
|
||||
const PaypalPayment = () => {
|
||||
const {
|
||||
cart,
|
||||
actions: { completeCart, setPaymentSession },
|
||||
} = useCart()
|
||||
const [errorMessage, setErrorMessage] = useState(undefined)
|
||||
const [processing, setProcessing] = useState(false)
|
||||
|
||||
const client = useMedusa()
|
||||
|
||||
const paypalSession = useMemo(() => {
|
||||
if (cart.payment_sessions) {
|
||||
return cart.payment_sessions.find(
|
||||
(s) => s.processor_id === "paypal"
|
||||
)
|
||||
}
|
||||
|
||||
return null
|
||||
}, [cart.payment_sessions])
|
||||
|
||||
if (!paypalSession) {
|
||||
return null
|
||||
}
|
||||
|
||||
const completeOrder = async (authorizationOrder) => {
|
||||
const cart = await setPaymentSession("paypal")
|
||||
|
||||
if (!cart) {
|
||||
setProcessing(false)
|
||||
return
|
||||
}
|
||||
|
||||
await client.carts.updatePaymentSession(cart.id, "paypal", {
|
||||
data: {
|
||||
data: {
|
||||
...authorizationOrder,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const order = await completeCart(cart.id)
|
||||
|
||||
if (!order || order.object !== "order") {
|
||||
setProcessing(false)
|
||||
return
|
||||
}
|
||||
|
||||
setProcessing(false)
|
||||
navigate("/order-confirmed", { state: { order } })
|
||||
}
|
||||
|
||||
const handlePayment = (data, actions) => {
|
||||
actions.order.authorize().then((authorization) => {
|
||||
if (authorization.status !== "COMPLETED") {
|
||||
setErrorMessage(
|
||||
`An error occurred, status: ${authorization.status}`
|
||||
)
|
||||
setProcessing(false)
|
||||
return
|
||||
}
|
||||
|
||||
completeOrder(authorization)
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<PayPalScriptProcessor options={{
|
||||
"client-id": paypalClientId,
|
||||
"currency": cart.region.currency_code.toUpperCase(),
|
||||
"intent": "authorize",
|
||||
}}>
|
||||
{errorMessage && (
|
||||
<span className="text-rose-500 mt-4">
|
||||
{errorMessage}
|
||||
</span>
|
||||
)}
|
||||
<PayPalButtons
|
||||
style={{ layout: "horizontal" }}
|
||||
onApprove={handlePayment}
|
||||
disabled={processing}
|
||||
/>
|
||||
</PayPalScriptProcessor>
|
||||
)
|
||||
}
|
||||
|
||||
export default PaypalPayment
|
||||
```
|
||||
|
||||
Here’s briefly what this code snippet does:
|
||||
|
||||
1. This component renders a PayPal button to initialize the payment using PayPal. You use the components from the PayPal React components library to render the button and you pass the `PayPalScriptProcessor` component the Client ID.
|
||||
2. When the button is clicked, the `handlePayment` function is executed. In this method, you initialize the payment authorization using `actions.order.authorize()`. It takes the customer to another page to log in with PayPal and authorize the payment.
|
||||
3. After the payment is authorized successfully on PayPal’s portal, the fulfillment function passed to `actions.order.authorize().then` will be executed which calls the `completeOrder` function.
|
||||
4. In `completeOrder`, you first ensure that the payment session for the PayPal payment processor is set as the [selected Payment Session in the cart](/api/store/#tag/Cart/operation/PostCartsCartPaymentSession). Then, you send a request to the backend to [update the payment session](/api/store#tag/Cart/operation/PostCartsCartPaymentSessionUpdate) data with the authorization data received from PayPal.
|
||||
5. You then [complete the cart and place the order](/api/store/#tag/Cart/operation/PostCartsCartComplete). If that is done successfully, you navigate to the `/order-confirmed` page.
|
||||
|
||||
The last step is to add this component as the component to render when PayPal is available as a payment processor.
|
||||
|
||||
In `src/components/payment/index.js` you’ll find in the return statement a switch statement that checks the payment processor for each payment session and renders the component based on the ID. Add before the `default` case a case for `paypal`:
|
||||
|
||||
```jsx title=src/components/payment/index.js
|
||||
switch (ps.processor_id) {
|
||||
case "stripe":
|
||||
// ...
|
||||
break
|
||||
case "manual":
|
||||
// ...
|
||||
break
|
||||
case "paypal":
|
||||
return <PaypalPayment />
|
||||
default:
|
||||
return null
|
||||
}
|
||||
```
|
||||
|
||||
Make sure to also import the `PayPalPayment` component at the top of the file:
|
||||
|
||||
```jsx
|
||||
import PaypalPayment from "./paypal-payment"
|
||||
```
|
||||
|
||||
That’s all you need to integrate PayPal into the Gatsby storefront.
|
||||
|
||||
Now, start the Medusa backend and the Gatsby storefront backend. Try adding an item into the cart and proceeding to checkout. When you reach the payment step, you should see the PayPal button.
|
||||
|
||||

|
||||
|
||||
You can test out the payment with PayPal using your sandbox account.
|
||||
|
||||
### Add to Custom Storefront
|
||||
|
||||
This section guides you to add PayPal into a React-based framework. The instructions are general instructions that you can use in your storefront.
|
||||
|
||||
@@ -146,30 +146,6 @@ Now, if you run your Medusa backend and your storefront, on checkout you’ll be
|
||||
|
||||

|
||||
|
||||
### Add to Gatsby Storefront
|
||||
|
||||
:::note
|
||||
|
||||
Medusa's Gatsby storefront is deprecated and it is recommended to use the [Next.js storefront](../../starters/nextjs-medusa-starter.mdx) or build your own storefront instead.
|
||||
|
||||
:::
|
||||
|
||||
In your `.env.development` file (or the file you’re using for your environment variables) add the following variable with the value set to the Publishable Key:
|
||||
|
||||
```jsx title=.env.development
|
||||
GATSBY_STRIPE_KEY=pk_
|
||||
```
|
||||
|
||||
:::note
|
||||
|
||||
You might find this environment variable already available so you can just replace its value with your Publishable Key.
|
||||
|
||||
:::
|
||||
|
||||
Now, if you run your Medusa backend and your storefront, on checkout you’ll be able to use Stripe.
|
||||
|
||||

|
||||
|
||||
### Add to Custom Storefront
|
||||
|
||||
This section will go over how to add Stripe into a React-based framework. The instructions are general instructions that you can use in your storefront.
|
||||
|
||||
@@ -287,134 +287,13 @@ To make sure the Next.js storefront properly displays the products in the search
|
||||
|
||||

|
||||
|
||||
### Add to Gatsby and React-Based Storefronts
|
||||
### Add to Other Storefronts
|
||||
|
||||
This section covers adding the search UI to React-based storefronts. It uses the Gatsby storefront as an example, but you can use the same steps on any React-based framework.
|
||||
|
||||
:::tip
|
||||
|
||||
For other frontend frameworks, please check out [Algolia’s Integrations guide](https://www.algolia.com/developers/?ui-libraries&client-libraries) for steps based on your framework.
|
||||
|
||||
:::
|
||||
|
||||
In the directory that contains your storefront, run the following command to install the necessary dependencies:
|
||||
|
||||
```bash npm2yarn
|
||||
npm install algoliasearch react-instantsearch-dom
|
||||
```
|
||||
|
||||
Then, add the following environment variables:
|
||||
|
||||
```bash
|
||||
GATSBY_ALGOLIA_APP_ID=<YOUR_APP_ID>
|
||||
GATSBY_ALGOLIA_SEARCH_API_KEY=<YOUR_SEARCH_API_KEY>
|
||||
GATSBY_SEARCH_INDEX_NAME=products
|
||||
```
|
||||
|
||||
Where `<YOUR_APP_ID>` and `<YOUR_SEARCH_API_KEY>` are respectively the Application ID and Search-Only API Key on the [API Keys page](#retrieve-api-keys).
|
||||
|
||||
:::note
|
||||
|
||||
In Gatsby, environment variables that should be public and available in the browser are prefixed with `GATSBY_`. If you’re using another React-based framework, you might need to use a different prefix to ensure these variables can be used in your code. Please refer to your framework’s documentation for help on this.
|
||||
|
||||
:::
|
||||
|
||||
Then, create the file `src/components/header/search.jsx` with the following content:
|
||||
|
||||
```jsx title=src/components/header/search.jsx
|
||||
import {
|
||||
Highlight,
|
||||
Hits,
|
||||
InstantSearch,
|
||||
SearchBox,
|
||||
connectStateResults,
|
||||
} from "react-instantsearch-dom"
|
||||
|
||||
import React from "react"
|
||||
import algoliasearch from "algoliasearch/lite"
|
||||
|
||||
const searchClient = algoliasearch(
|
||||
process.env.GATSBY_ALGOLIA_APP_ID,
|
||||
process.env.GATSBY_ALGOLIA_SEARCH_API_KEY
|
||||
)
|
||||
|
||||
const Search = () => {
|
||||
const Results = connectStateResults(
|
||||
({ searchState, searchResults, children }) => {
|
||||
return (
|
||||
searchState && searchState.query &&
|
||||
searchResults && searchResults.nbHits !== 0 ?
|
||||
(
|
||||
<div
|
||||
className="absolute ...">
|
||||
{children}
|
||||
</div>
|
||||
) : (
|
||||
<div></div>
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="relative">
|
||||
<InstantSearch
|
||||
indexName={process.env.GATSBY_SEARCH_INDEX_NAME}
|
||||
searchClient={searchClient}>
|
||||
<SearchBox submit={null} reset={null} />
|
||||
<Results>
|
||||
<Hits hitComponent={Hit} />
|
||||
</Results>
|
||||
</InstantSearch>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const Hit = ({ hit }) => {
|
||||
return (
|
||||
<div key={hit.id} className="relative">
|
||||
<div className="hit-name">
|
||||
<Highlight attribute="title" hit={hit} tagName="mark" />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Search
|
||||
```
|
||||
|
||||
This file uses the dependencies you installed to show the search results. It also initializes Algolia using the environment variables you added.
|
||||
|
||||
:::note
|
||||
|
||||
If you named your environment variables differently based on your framework, make sure to rename them here as well.
|
||||
|
||||
:::note
|
||||
|
||||
Finally, import this file at the beginning of `src/components/header/index.jsx`:
|
||||
|
||||
```jsx title=src/components/header/index.jsx
|
||||
import Search from "./search"
|
||||
```
|
||||
|
||||
And add the `Search` component in the returned JSX before `RegionPopover`:
|
||||
|
||||
```jsx title=src/components/header/index.jsx
|
||||
// ...
|
||||
<div className="...">
|
||||
<Search />
|
||||
<RegionPopover regions={mockData.regions} />
|
||||
</div>
|
||||
// ...
|
||||
```
|
||||
|
||||
If you run your Gatsby storefront while the Medusa backend is running, you should find a search bar in the header of the page. Try entering a query to search through the products in your store.
|
||||
|
||||

|
||||
To integrate Algolia's search functionalities in your storefront, please refer to [Algolia's InstantSearch.js documentation](https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/js/). You'll find packages for different frontend frameworks and how you can use them.
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [Deploy your Medusa backend](../../deployments/server/index.mdx)
|
||||
- [Deploy your Gatsby storefront](../../deployments/storefront/deploying-gatsby-on-netlify.md)
|
||||
- [Deploy your storefront](../../deployments/storefront/index.mdx)
|
||||
|
||||
@@ -251,136 +251,13 @@ To make sure the Next.js storefront properly displays the products in the search
|
||||
|
||||

|
||||
|
||||
### Add to Gatsby and React-Based Storefronts
|
||||
### Add to Other Storefronts
|
||||
|
||||
This section covers adding the search UI to React-based storefronts. It uses the Gatsby storefront as an example, but you can use the same steps on any React-based framework.
|
||||
|
||||
:::tip
|
||||
|
||||
For other frontend frameworks, please check out [MeiliSearch’s Integrations guide](https://github.com/meilisearch/integration-guides) for steps based on your framework.
|
||||
|
||||
:::
|
||||
|
||||
In the directory that contains your storefront, run the following command to install the necessary dependencies:
|
||||
|
||||
```bash npm2yarn
|
||||
npm install react-instantsearch-dom @meilisearch/instant-meilisearch
|
||||
```
|
||||
|
||||
Then, add the following environment variables:
|
||||
|
||||
```bash
|
||||
GATSBY_MEILISEARCH_HOST=<YOUR_MEILISEARCH_HOST>
|
||||
GATSBY_MEILISEARCH_API_KEY=<YOUR_API_KEY>
|
||||
GATSBY_SEARCH_INDEX_NAME=products
|
||||
```
|
||||
|
||||
Make sure to replace `<YOUR_MEILISEARCH_HOST>` with your MeiliSearch host and `<YOUR_API_KEY>` with the API key you created as instructed in the [Storefront Prerequisites](#storefront-prerequisites) section.
|
||||
|
||||
:::caution
|
||||
|
||||
In Gatsby, environment variables that should be public and available in the browser are prefixed with `GATSBY_`. If you’re using another React-based framework, you might need to use a different prefix to ensure these variables can be used in your code. Please refer to your framework’s documentation for help on this.
|
||||
|
||||
:::
|
||||
|
||||
Then, create the file `src/components/header/search.jsx` with the following content:
|
||||
|
||||
```jsx title=src/components/header/search.jsx
|
||||
import {
|
||||
Highlight,
|
||||
Hits,
|
||||
InstantSearch,
|
||||
SearchBox,
|
||||
connectStateResults,
|
||||
} from "react-instantsearch-dom"
|
||||
|
||||
import React from "react"
|
||||
import {
|
||||
instantMeiliSearch,
|
||||
} from "@meilisearch/instant-meilisearch"
|
||||
|
||||
const searchClient = instantMeiliSearch(
|
||||
process.env.GATSBY_MEILISEARCH_HOST,
|
||||
process.env.GATSBY_MEILISEARCH_API_KEY
|
||||
)
|
||||
|
||||
const Search = () => {
|
||||
const Results = connectStateResults(
|
||||
({ searchState, searchResults, children }) => {
|
||||
return (
|
||||
searchState && searchState.query &&
|
||||
searchResults && searchResults.nbHits !== 0 ?
|
||||
(
|
||||
<div
|
||||
className="absolute ...">
|
||||
{children}
|
||||
</div>
|
||||
) : (
|
||||
<div></div>
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="relative">
|
||||
<InstantSearch
|
||||
indexName={process.env.GATSBY_SEARCH_INDEX_NAME}
|
||||
searchClient={searchClient}>
|
||||
<SearchBox submit={null} reset={null} />
|
||||
<Results>
|
||||
<Hits hitComponent={Hit} />
|
||||
</Results>
|
||||
</InstantSearch>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const Hit = ({ hit }) => {
|
||||
return (
|
||||
<div key={hit.id} className="relative">
|
||||
<div className="hit-name">
|
||||
<Highlight attribute="title" hit={hit} tagName="mark" />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Search
|
||||
```
|
||||
|
||||
This file uses the dependencies you installed to show the search results. It also initializes MeiliSearch using the environment variables you added.
|
||||
|
||||
:::caution
|
||||
|
||||
If you named your environment variables differently based on your framework, make sure to rename them here as well.
|
||||
|
||||
:::
|
||||
|
||||
Finally, import this file at the beginning of `src/components/header/index.jsx`:
|
||||
|
||||
```jsx title=src/components/header/index.jsx
|
||||
import Search from "./search"
|
||||
```
|
||||
|
||||
And add the `Search` component in the returned JSX before `RegionPopover`:
|
||||
|
||||
```jsx title=src/components/header/index.jsx
|
||||
// ...
|
||||
<div className="...">
|
||||
<Search />
|
||||
<RegionPopover regions={mockData.regions} />
|
||||
</div>
|
||||
// ...
|
||||
```
|
||||
|
||||
If you run your Gatsby storefront while the Medusa backend and the MeiliSearch instance are running, you should find a search bar in the header of the page. Try entering a query to search through the products in your store.
|
||||
|
||||

|
||||
To integrate MeiliSearch's search functionalities in your storefront, please refer to [MeiliSearch's documentation](https://docs.meilisearch.com/learn/what_is_meilisearch/sdks.html#front-end-tools). They offer different tools that you can use based on the frontend framework of your storefront.
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [Deploy your Medusa backend](../../deployments/server/index.mdx).
|
||||
- [Deploy your Gatsby storefront](../../deployments/storefront/deploying-gatsby-on-netlify.md).
|
||||
- [Deploy your storefront](../../deployments/storefront/index.mdx).
|
||||
|
||||
Reference in New Issue
Block a user