App reviews, troubleshooting, and recommendations
It's frustrating I can't make such simple thing as redirecting user to another app page after form submitting.
I'm using recommended Remix cli template. I tried different approaches but they all fail.
Here is my app/routes/_index/route.jsx
import { useState } from "react"; import { useActionData } from "@remix-run/react"; import { authenticate } from "../../shopify.server"; import { AppProvider, Button, Text, ... } from "@shopify/polaris"; export default function App() { ... const handleSubmit = async (event) => { event.preventDefault(); setUiState('saving'); // handling data ... here i need to redirect user to some page inside the app. let's say Test page. How? //open('/app/test', '_self'); //navigate('/app/test'); // const { redirect } = await authenticate.admin(request); // return redirect('/app/test');
I'm getting different errors but none of the attempts was successful.
- with redirect()
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'admin')
- with open()
xxx.trycloudflare.com redirected you too many times.
- with const navigate = useNavigate();
Uncaught (in promise) Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
So what's the right method for this? Can you help please?
Hi there. Shopify encourages using the Admin redirect helper for embedded apps. However, this helper must be called from within a Remix loader or action function. See below for usage examples.
From the error output you provided, it looks like the admin context isn't loading correctly. Try changing the authenticate import path from "../../shopify.server" to "../shopify.server". Also, you might want to try moving your application logic from the app/routes/_index/route.jsx file to the app/routes/app._index.jsx file, as this is the main app landing page (though this may vary depending on the type of application you are developing.)
Use loader if you want the user to be redirected before page is loaded.
import { authenticate } from "../shopify.server";
export const loader = async ({ request }) => {
const { session, redirect } = await authenticate.admin(request);
// App logic, if needed
return redirect("/app/other_page");
};
Use action if you want to collect data from the user, then redirect on submit.
import { Form, useActionData, useSubmit } from "@remix-run/react";
import { authenticate } from "../shopify.server";
export const action = async ({ request }) => {
const { session, redirect } = await authenticate.admin(request);
// Await user form submission data
const formData = await request.formData();
// Do stuff with the data
return redirect("/app/other_page");
};
export default function Index() {
const actionData = useActionData();
const submit = useSubmit();
const handleSave = () => submit(formData, { method: "POST" });
return (
<Form>
<TextField value={userdata} label="Enter your data" type="text" name="userdata" />
<Button variant="primary" onclick={handleSave} >Save</Button>
</Form>
)
}
Thanks for you reply! But I still can't get it working.
I used your code and updated it a little to avoid raising errors.
However when I click the button nothing happens, no "start action" in console, no errors. What's wrong? Why action is not even triggered?
Here is my current code for this very basic page:
import { Form, redirect, useActionData, useSubmit } from "@remix-run/react";
import { authenticate } from "../../shopify.server";
import { useState } from "react";
import {
AppProvider,
TextField,
Button,
} from "@shopify/polaris";
export const action = async ({ request }) => {
console.log("start action");
const { session, redirect } = await authenticate.admin(request);
// Await user form submission data
const formData = await request.formData();
// Do stuff with the data
return redirect("/app/instructions");
};
export default function Index() {
const [username, setUsername] = useState("");
const formData = useActionData();
const submit = useSubmit();
const handleSave = () => submit(formData, { method: "POST" });
const i18n = {
Polaris: {
ResourceList: {
},
},
};
const setUserdata = (value) => {
console.log(value);
setUsername(value);
}
return (
<AppProvider i18n={i18n}>
<Form method="post">
<TextField value={username}
onChange={setUserdata}
label="Enter your data" type="text" name="username" />
<Button variant="primary" onClick={handleSave} >Save</Button>
</Form>
</AppProvider>
)
}
Hi @awidget ,
I see you're trying to submit a formData using the action. But the formData variable is out of scope for handleSave function. Since you're already using a state and a useSubmit to programmatically submit the form, I suggest instead of trying to use the formData, you use the username state itself.
That way you can make sure that the post request has a body. By default, if you don't give any value or undefined as the request body, the remix will automatically redirect the request to the loader function instead of the action function. I've modified you're handleSave function code to run the action function as you submit the form.
const handleSave = () => submit({ username }, { method: "POST" });
The result is
Kazi Muktadir Ahmed | Brain Station 23
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
I am having an issue with redirects after i build my app using the npm run build command and putting it one the server
below is the code
Hey Community! As we jump into 2025, we want to give a big shout-out to all of you wh...
By JasonH Jan 7, 2025Hey Community! As the holiday season unfolds, we want to extend heartfelt thanks to a...
By JasonH Dec 6, 2024Dropshipping, a high-growth, $226 billion-dollar industry, remains a highly dynamic bus...
By JasonH Nov 27, 2024