I am having an issue figuring out how to display html in the admin for an app.
I have followed the ‘Build a Shopify app with Node and Express’ tutorial, and am able to display json of the shop in the Shopify App Admin. However, I am not understanding the next steps of getting any html to display in the app admin. I have tried replacing the end(shopResponse)
with a render method, which throws the error ‘request origin cannot be verified’. I have also tried to set up an additional request, but that caused a similar error.
app.get('/shopify', (req, res) => {
const shop = req.query.shop;
if (shop) {
const state = nonce();
const redirectUri = forwardingAddress + '/shopify/callback';
const installUrl = 'https://' + shop +
'/admin/oauth/authorize?client_id=' + apiKey +
'&scope=' + scopes +
'&state=' + state +
'&redirect_uri=' + redirectUri;
res.cookie('state', state);
res.redirect(installUrl);
} else {
return res.status(400).send('Missing shop parameter. Please add ?shop=your-development-shop.myshopify.com to your request');
}
});
app.get('/shopify/callback', (req, res) => {
const { shop, hmac, code, state } = req.query;
console.log(req.headers)
var stateCookie = '';
if (req.headers.cookie) {
stateCookie = cookie.parse(req.headers.cookie).state;
}
if (state !== stateCookie) {
return res.status(403).send('Request origin cannot be verified');
}
if (shop && hmac && code) {
const map = Object.assign({}, req.query);
delete map['signature'];
delete map['hmac'];
const message = querystring.stringify(map);
const providedHmac = Buffer.from(hmac, 'utf-8');
const generatedHash = Buffer.from(
crypto
.createHmac('sha256', apiSecret)
.update(message)
.digest('hex'),
'utf-8'
);
let hashEquals = false;
// timingSafeEqual will prevent any timing attacks. Arguments must be buffers
try {
hashEquals = crypto.timingSafeEqual(generatedHash, providedHmac)
// timingSafeEqual will return an error if the input buffers are not the same length.
} catch (e) {
hashEquals = false;
};
if (!hashEquals) {
return res.status(400).send('HMAC validation failed');
}
const accessTokenRequestUrl = 'https://' + shop + '/admin/oauth/access_token';
const accessTokenPayload = {
client_id: apiKey,
client_secret: apiSecret,
code,
};
request.post(accessTokenRequestUrl, { json: accessTokenPayload })
.then((accessTokenResponse) => {
const accessToken = accessTokenResponse.access_token;
// DONE: Use access token to make API call to 'shop' endpoint
const shopRequestUrl = 'https://' + shop + '/admin/api/2019-04/themes.json';
const shopRequestHeaders = {
'X-Shopify-Access-Token': accessToken,
};
request.get(shopRequestUrl, { headers: shopRequestHeaders })
.then((shopResponse) => {
// This is what I have tried replacing with a render method
res.status(200).end(shopResponse);
})
.catch((error) => {
res.status(error.statusCode).send(error.error.error_description);
});
})
.catch((error) => {
res.status(error.statusCode).send(error.error.error_description);
});
} else {
res.status(400).send('Required parameters missing');
}
});
I am expecting to be able to see basic html in the Shopify app admin.
SOLVED
After reading accepted answer, I realized I didn’t need all the auth from the getting started to show the file.
My whitelisted route ended up looking like this:
app.get('/shopify/callback', (req, res) => {
res.render('pages/index')
});
3
Answers
Edited: I am also new to developing for Shopify and have been spending the last 3 weeks adjusting my Node / Express apps to work with Shopify and I am having bumps in the road as well.
I just reviewed this tonight (4/25/19) and here is what I did to render / show my index.html page.
Add this to the top with your other requirements:
Add this path in:
Note: The ‘../pubic’ is the directory right before my ‘index.html’ file. This will probably be different for you, but it should be easy to figure out.
I also added in this path as well:
You don’t display your HTML in Shopify Admin. Instead, you render HTML in your App, and Shopify displays your App embedded inside the Shopify Admin. You have two choices. One is that your App is rendered outside the Admin as per any other normal web App, or two, you choose to render inside the Shopify admin as an embedded App which means your HTML displays inside an iframe Shopify creates for you.
You should really read the documentation on Shopify Apps before making an App and then asking how Apps display HTML… it is important you understand the basic concept of that.
Once you getting shop json succesfully it means app installed in shopify store successfully
To Display html in app for store admin you have to create one route in your project which render you to html page like as below
this can render you to html page where you can display html for your app home page
Now you have to set your domain url in your shopify partner account app setup
Shopify partner account
click this url and
go to your app >> app setup and add your https domain for your app
this root location load when your app open from shopify admin and it display you index html page for your app