Hi,
I am new to Shopify development and React (although I have developed for NodeJS Express before).
Following the steps in the 'Build a Shopify App with Node and React tutorial' (https://shopify.dev/tutorials/build-a-shopify-app-with-node-and-react/build-your-user-interface-with...), I have hit a snag.
At the point of setting the Shopify App Bridge, the instructions say to add a <Provider config={config}> tag. Having defined config previously as: { apiKey: API_KEY, shopOrigin: Cookies.get("shopOrigin"), forceRedirect: true }
The problem is, as I can see in the example code provided in the tutorial, API_KEY is not defined, and predictably I get the appropriate error when testing the app from the Store admin. Even if I define API_KEY as the SHOPIFY_API_KEY from process.env, I encounter a new error: apiKey must be provided.
I'm officially at a loss. Any help would be appreciated.
Hi @tobrien,
The API_KEY value here is expected to be set as an environment variable within your app. One way of doing that is to set the value as a webpack plugin (at compile time) in your next.config.js file like so:
const apiKey = JSON.stringify(process.env.SHOPIFY_API_KEY); module.exports = withCSS({ webpack: config => { const env = { API_KEY: apiKey }; config.plugins.push(new webpack.DefinePlugin(env)); return config; } });
You can find some more information on DefinePlugin in the webpack docs.
Hope this helps!
Paulo
Hi @paulomarg
Thank you for your response. I did forget to mention I have included this in my next.config.js:
require("dotenv").config() const withCSS = require('@zeit/next-css') const webpack = require('webpack') const apiKey = JSON.stringify(process.env.SHOPIFY_API_KEY) module.exports = withCSS({ webpack: (config) => { const env = { API_KEY: apiKey } config.plugins.push(new webpack.DefinePlugin(env)) return config } })Am I missing something obvious (like a typo)? Is it something to do with how I am starting the application or the structure of my project?
Hi again!
This looks OK to me, the demo project is set up so API_KEY should be set at that point. It could indeed be some other issue as you said.
The first thing I'd suggest is to make sure that your API key is set in your .env file, and to check that the value is being set at this point when you recompile your project.
For anyone else that encounters this, a restart of ngrok seemed to do the trick. Although I'm sure I had done that before posting, this also resolved the issue when I subsequently encountered the error.
Of course first check that next.config.js is set up properly as described.
Hi @samsuzuki,
Can you please provide a bit more detail on the error you're seeing, like when does it happen, and the code that triggers it?
Also, just to check all the boxes, make sure your API key is set in your .env file and is being properly loaded when your server starts.
Thank you!
@paulomarg Thank you for your reply. Sorry for my lack of information.
I'm new as a React/ Node.js developer( usually I am a iOS app developer).
And I was doing this tutorial . It works fine halfway.
But, at this part(#Add Shopify Bridge), my code does not work fine. Before 'Add Shopify Bridge' section, my code works fine.
When I open below URL(my ngrok with OAuth) after writing "Add Shopify Bridge" code with restarting web-server and ngrok, this error message appear.
https://24e3f0c517ea.ngrok.io/auth?shop=xn-ccka2ewcwdtfo276cihcb50i.myshopify.com
Error Message:
Unhandled Runtime ErrorAppBridgeError: APP::ERROR::INVALID_CONFIG: apiKey must be provided
Browser(Google Chrome) console error message:
My development enviroment
"@shopify/app-bridge-react": "^1.26.2","@shopify/koa-shopify-auth": "^3.1.65","@shopify/polaris": "^5.2.0","@zeit/next-css": "^1.0.1","dotenv": "^8.2.0","isomorphic-fetch": "^2.2.1","js-cookie": "^2.2.1","koa": "^2.13.0","koa-session": "^6.0.0","next": "^9.5.2","react": "^16.13.1","react-dom": "^16.13.1"
My code is below.
/.env
SHOPIFY_API_KEY='xxxxxxxx'
SHOPIFY_API_SECRET_KEY='xxxxxxx'
/server.js
require('isomorphic-fetch');
const dotenv = require('dotenv');
const Koa = require('koa');
const next = require('next');
const { default: createShopifyAuth } = require('@shopify/koa-shopify-auth');
const { verifyRequest } = require('@shopify/koa-shopify-auth');
const session = require('koa-session');
dotenv.config();
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
const { SHOPIFY_API_SECRET_KEY, SHOPIFY_API_KEY } = process.env;
app.prepare().then(() => {
const server = new Koa();
server.use(session({ secure: true, sameSite: 'none' }, server));
server.keys = [SHOPIFY_API_SECRET_KEY];
server.use(
createShopifyAuth({
apiKey: SHOPIFY_API_KEY,
secret: SHOPIFY_API_SECRET_KEY,
scopes: ['read_products'],
afterAuth(ctx) {
const { shop, accessToken} = ctx.session;
ctx.cookies.set('shopOrigin', shop, {
httpOnly: false,
secure: true,
sameSite: 'none'
});
ctx.redirect('/');
},
}),
);
server.use(verifyRequest());
server.use(async (ctx) => {
await handle(ctx.req, ctx.res);
ctx.respond = false;
ctx.res.statusCode = 200;
return
});
server.listen(port, () => {
console.log(`> Ready on http://localhost:${port}`);
});
});
/page/_app.js
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';
class MyApp extends App {
render() {
const { Component, pageProps } = this.props;
const config = { apiKey: API_KEY, shopOrigin: Cookies.get("shopOrigin"), forceRedirect: true };
return (
<React.Fragment>
<Head>
<title>Sample App</title>
<meta charSet="utf-8" />
</Head>
<Provider config={config}>
<AppProvider i18n={translations}>
<Component { ...pageProps} />
</AppProvider>
</Provider>
</React.Fragment>
);
}
}
export default MyApp;
/page/index.js
import { EmptyState, Layout, Page, TextStyle } from '@shopify/polaris';
import { TitleBar } from '@shopify/app-bridge-react';
const img = 'https://cdn.shopify.com/s/files/1/0757/9955/files/empty-state.svg';
const Index = () => (
<Page>
<TitleBar
title="Sample App"
primaryAction={{
content: 'Select products',
}}
/>
<Layout>
<EmptyState
heading="Discount your products temporarily"
action={{
content: 'Select products',
onAction: () => console.log('clicked!'),
}}
image={img}
>
<p>Select products to change their price temporarily.</p>
</EmptyState>
</Layout>
</Page>
);
export default Index;
Other code: same as codes before 'Add Shopify Bridge' section
Thank you for your support.
@paulomarg Also, "/next.config.js" is here.
require("dotenv").config();
const withCSS = require('@zeit/next-css');
const webpack = require('webpack');
const apiKey = JSON.stringify(process.env.SHOPFIY_API_KEY);
module.exports = withCSS({
webpack: (config) => {
const env = { API_KEY: apiKey};
config.plugins.push(new webpack.DefinePlugin(env));
return config;
},
});
Thank you.
@paulomarg I solved! Sorry for bothering you.
The reason of the error is here.
const apiKey = JSON.stringify(process.env.SHOPFIY_API_KEY);
" SHOPFIY" is typo.
User | Count |
---|---|
16 | |
12 | |
7 | |
6 | |
5 |