Skip to content
  • Unlock Pro
  • Log in with GitHub
Profile
OverviewSolutions
3
Comments
1

22-22

@22-22100 points

I’m a mysterious individual who has yet to fill out my bio. One thing’s for certain: I love writing front-end code!

Latest solutions

  • E-commerce product page (Next.js + Tailwind.css)

    #next#react#typescript#tailwind-css

    22-22•100
    Submitted 4 months ago
    1. 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.

    2. What's the best way to make components for the PhotoGallery and PhotoGalleryModal to make PhotoGallery reusable and not to repeat the code?

    3. 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?


    0 comments
  • Loopstudios landing page (Next.js + Tailwind.css)

    #next#react#typescript#tailwind-css

    22-22•100
    Submitted 6 months ago

    What's the best way to render components/elements conditionally? For example, See all button is in different places in a desktop and mobile version.


    0 comments
  • URL shortening app (my first try with NextJS and TailwindCSS!)

    #next#react#tailwind-css#typescript#tanstack-query

    22-22•100
    Submitted 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!


    1 comment

Latest comments

  • Orji Dominion Ebubennia•390
    @dodosebn
    Submitted 7 months ago

    next js and typescript project 102

    #motion#next#react#tailwind-css#fetch
    1
    22-22•100
    @22-22
    Posted 7 months ago

    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

Stay up to datewith new challenges, featured solutions, selected articles, and our latest news

Frontend Mentor

  • Unlock Pro
  • Contact us
  • FAQs
  • Become a partner

Explore

  • Learning paths
  • Challenges
  • Solutions
  • Articles

Community

  • Discord
  • Guidelines

For companies

  • Hire developers
  • Train developers
© Frontend Mentor 2019 - 2025
  • Terms
  • Cookie Policy
  • Privacy Policy
  • License

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub

Oops! 😬

You need to be logged in before you can do that.

Log in with GitHub