For discussing the development and usage of Checkout UI extensions, post-purchase extensions, web pixels, Customer Accounts UI extensions, and POS UI extensions
Apologies that this isn't exactly on the right board - there isn't any app dev spots to post it in.
I have used the Shopify CLI to create a Remix app. I need to receive customer usage data which will be processed and stored in the prisma DB. This is sent via the shopify app proxy.
If I setup a Remix route action to process the data, I receive the data ok but the response to the client is the page of that route. This doesn't seem like the right way to do it.
Am I better off running an Express server alongside the Remix app to process the incoming data and push it to the prisma db which the app can then reference?
I'm new to Remix (and app dev in general), so sorry if there is an obvious answer to this.
Solved! Go to the solution
This is an accepted solution.
I figured it out.
I was returning the component in the jsx file when I should have removed it when using this route as an API to process POST requests. It gets sent to the client as a response instead of the response from the action.
Bad:
import { json } from '@remix-run/node';
export async function action({ request }) {
try {
const data = await request.json();
// process data
const response = {};
return json(response);
} catch (error) {
// handle error
}
}
export default function incoming() {
}
Good:
import { json } from '@remix-run/node';
export async function action({ request }) {
try {
const data = await request.json();
// process data
const response = {};
return json(response);
} catch (error) {
// handle error
}
}
This is an accepted solution.
I figured it out.
I was returning the component in the jsx file when I should have removed it when using this route as an API to process POST requests. It gets sent to the client as a response instead of the response from the action.
Bad:
import { json } from '@remix-run/node';
export async function action({ request }) {
try {
const data = await request.json();
// process data
const response = {};
return json(response);
} catch (error) {
// handle error
}
}
export default function incoming() {
}
Good:
import { json } from '@remix-run/node';
export async function action({ request }) {
try {
const data = await request.json();
// process data
const response = {};
return json(response);
} catch (error) {
// handle error
}
}
cool, i created a new remix route and removed the default export, now i can fetch my data in dev environment use the localhost url shopify provide to me. but what url should i use if i want to deploy it on online store?
The URL you will be using in production to access the route will be the domain that you have set up for the app. So it could be 'https://myappurl.com/route/data' for example. This is if I understand you correctly.
For local development, I run a tunnel that points to the app. This way you don't have to keep changing the app URL each time you restart the app during development. I have setup a cloudflare tunnel and I launch it with their CLI.
You have to define a couple of things in the TOML files for this to work...
shopify.web.toml: You'll need to define the port for the app to use
name = "remix"
roles = ["frontend", "backend"]
webhooks_path = "/webhooks"
port = 8001
[commands]
dev = "npm exec remix dev"
[hmr_server]
http_paths = ["/ping"]
shopify.app.toml: Assign the tunnel URL to the application_url and the redirect_urls
# Learn more about configuring your app at https://shopify.dev/docs/apps/tools/cli/configuration
name = "postgres-starter"
client_id = "****"
application_url = "https://your-tunnel-url.com"
embedded = true
[access_scopes]
# Learn more at https://shopify.dev/docs/apps/tools/cli/configuration#access_scopes
scopes = "write_products"
[auth]
redirect_urls = [
"https://your-tunnel-url.com/auth/callback",
"https://your-tunnel-url.com/auth/shopify/callback",
"https://your-tunnel-url.com/api/auth/callback"
]
[webhooks]
api_version = "2023-10"
[pos]
embedded = false
[build]
automatically_update_urls_on_dev = true
dev_store_url = "storename.myshopify.com"
I think you also need to update/check the URL in the app settings of the partner dashboard, and also within the app settings of the shopify admin (it's the Shopify App Proxy URL). I cant remember if these get updated automatically or not.
If you wanted to have the URL different in production and local development, you could use an ENV file where you set your development environment (dev/production). Your app would then set the appropriate URL depending on the environment. I usually use a ternary operator along the lines of:
const URL = process.env.ENVIRONMENT === 'dev' ? 'https://devurl.com' : 'https://produrl.com'
^^ This way, if you haven't defined the environment variable, it will fallback to the production URL.
Having said that (the environment variable idea), it only works in a node environment - it won't work in a browser. To get around it in a browser, I use a ternary operator and check the contents of the URL (it may contain 127.0.0.1 if you're devloping a theme locally, for example).
No worries. Glad I could be of some help!
In development, you should be able to access the data through the URL that points to your cloudflare tunnel. In production, this would be your app URL.
Is this not working for you?
Yep. I think it sounds like you're following correctly.
The remix template requires the app to be hosted externally, and that requires you to use the platform/server URL. Ideally you would register your own domain and set that up to point to your app.
Hi @Danh11 , wondering if you could share some more of your code in regards to getting Prisma to work with a Hydrogen/Remix build? I am having trouble getting the Prisma client to work correctly. (Did you have to use Prisma Accelerate to get this working?)
Thanks,
Aaron
amarkle@lofta.com
I haven't had to do that sorry, so I'm not really familiar with it. I've only been using the Shopify app remix template where Prisma is already setup. Depending on the app, and if you're wanting it to scale, I will swap out Prisma for another SQL storage solution as I have read that Prisma is not the best for production apps at scale. It's great for getting started quickly and has great syntax though! In my current app I have setup postgres and I'm using Supabase to host the database.
Ah k, thanks for the reply. I will rethink if Prisma is needed for my use case.
Hello @Danh11,
I am developing a Shopify App with Supabase as well. I'm Using Heroku for hosting the app and Supabase Postgress as the Database.
It works great, but I see some latency when I interact with my app.
Do you have any recommendations for using external database providers like supabase?
Where do you host your app?
I first started with the sqlite/prisma configuration of the remix starter template, which felt "blazingly fast" as fireship would say. Then after deploying to heroku I felt like it's not the best way to use a sqlite database in production, especially when I want to distribute the app across several shopify shops, so I tried hosting the shopify app at vercel with a vercel postgress database which worked very well, but for any reason I couldn't get the for my app necessary shopify admin graphQL requests to work.
Long story short, I switched back to heroku deployment and everything works fine with the supabase postgress database, but it feels like it takes significantly more time on each database query than before with SQLite. Now I'm asking myself if there is maybe still some potential for optimizing the whole shopify-remix-app-with-supabase-stack.
I was also thinking about using the supabase RLS, but I don't hat time to look into the shopify session auth handling mechanism.
I think it would be awesome to use supabase postgress with rls in combination with the shopify session mechanism.
Greetings from Germany
Michael
michael@kreativkonnekt.de
Lol @ the fireship quote!
I actually haven't deployed my app yet as I'm still working on it, so I can't shed any light on what latency I'm experiencing from the deployed app. Although I would assume it would be much the same compared to hitting the database when the app is running locally in dev seeing both would be making requests to an external server.
Come to think of it, I would probably expect a larger delay when querying a Supabase database, compared with SQLite/Prisma seeing one is being hosted on a remote server and the other is hosted on the same server as the app. That would be a benefit of using Prisma, but then you also have the downsides of using Prisma that people report.
I wonder why the graphQL requests weren't working with your app on vercel? Without knowing what was happening, I would think spending time to solve that issue might be well spent seeing they can host your database too. It would be nice to have the app hosted on the same platform that provides the database for low latency requests. I might try deploying to vercel when I'm ready and I will see what happens to my graphQL requests.
I also haven't yet enabled RLS on my Supabase database. It's on my list of things to investigate and implement as Supabase keeps yelling at me about it. It would definitely make it easy to stop one store being able to access another store's data.
Hi, where did you add this code? I've been trying to for hours and can't get it working. I've added a product.js file in app/routes/api/ and all it ever does it return the code on that page when going to the endpoint https://{cloudflare-url}/app/routes/api/products. What am i doing wrong here?
Hey, @Danh11 , do you know how to set up Shopify Remix app with a separate express server or have a template for it by any chance ?
No, sorry 🙂
Hey Dan any ideas on why I would be getting a 404 error when trying to make an app proxy request from my theme app extension, here is the code
I'm wondering if you need to include the store URL in your fetch request. You currently '/apps/proxy943/', but you might you need something like 'https://storename.myshopify.com/apps/proxy493'?
I was using an app proxy at one point but removed it since I took another direction with what I needed to use it for, so that's kind of a guess seeing it's been a while since using an app proxy.
In production I think you would get the domain from the current URL, but I've never implemented this personally so I can't be sure.
Also check that the 404 isn't being caused by a CORS issue. The way you handle and return CORS preflight requests can be a little finicky in remix apps.