Latest solutions
E-commerce product page (Next.js + Tailwind.css)
#next#react#typescript#tailwind-cssSubmitted 4 months ago-
Is it ok if I make a separate component for a mobile navigation (meaning I'm not reusing desktop navigation component)? A mobile nav is a modal window.
-
What's the best way to make components for the PhotoGallery and PhotoGalleryModal to make PhotoGallery reusable and not to repeat the code?
-
Where to have useState for cart modal? In the header? Then the whole component must be client. The same with the PhotoGallery modal which makes the Main.tsx a client component as well, is it ok?
-
Loopstudios landing page (Next.js + Tailwind.css)
#next#react#typescript#tailwind-cssSubmitted 6 months agoWhat's the best way to render components/elements conditionally? For example, See all button is in different places in a desktop and mobile version.
URL shortening app (my first try with NextJS and TailwindCSS!)
#next#react#tailwind-css#typescript#tanstack-querySubmitted 9 months ago-
My main question to how to deal with the data fetching and state management in NextJS (app router). What's the best way for submitting a form with NextJS app router and for a state management nowadays? (for such a small app like this one and for bigger ones)?
-
Is it a good idea in general to use NextJS app router?
-
What's the best practice for a form validation? I couldn't add a "required" html attribute to react custom validation because it was showing an error (a red border around an input) when it was empty even if it was on initial render, before the user started typing something. In the end I was saving an input value to the useState and checking
if (!url.trim()) { setError(emptyInputError) return }
-
Also I more specific question: how to prevent a form height from jumping when an error message is shown (for example, when an input is empty)?
Thank you for your help!
-
Latest comments
- @dodosebn@22-22
Hello,
Congratulations on your solutions! I recently finished the same challenge and got a very useful comment about the api request. I can see you are fetching first from the client to your server, and then fetching again from your server to an external api (I was doing the same). You are doing everything correctly in route.ts but if you need to execute a function on the server you can also use Server Actions. So instead of route.ts, in actions.ts file you can make a fetch POST request to the external api.
// /app/actions.ts "use server"; const externalApiUrl = "https://cleanuri.com/api/v1/shorten"; export async function shorten(url: string) { try { const externalResponse = await fetch(externalApiUrl, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ url }), }); const urlsData = await externalResponse.json(); return urlsData; } catch (error) { console.error("Error forwarding request:", error); return { error: "Failed to fetch data from the external API" }; } }
and instead of making another fetch in your Main component, you can directly call your action:
"use client"; ... const [isPending, startTransition] = useTransition(); async function handleSubmit(event: FormEvent<HTMLFormElement>) { startTransition(() => { // Call Server Action const result = await shorten(url); ... }); } return ( <form onSubmit={handleSubmit}> <button>{isPending ? "Submitting..." : "Shorten it!"}</button> </form> ); }
I was also recommended to use the libs for form validation, react-hook-form or formik, they are very helpful to track everything.
I hope you'll find it helpful!
Marked as helpful