Author: Joy kumar
Built-In components in Remix

Built-In components in Remix. How to use it effeciently

It is pre built component offer by remix to make application more optimistic.

<Await>

Imagine you are fetching a user's name from an API, and you want to display it once the data is resolved. Here's how you can use <Await> with <Suspense> to achieve this:

import React, { Suspense } from "react";
import { Await } from "@remix-run/react";

// Simulate a promise to fetch user data
const fetchUserName = new Promise((resolve) => {
  setTimeout(() => {
    resolve("Abhay");
  }, 2000); // Resolves after 2 seconds
});

export default function App() {
  return (
    <div>
      <h1>User Data</h1>
      <Suspense fallback={<div>Loading...</div>}>
        <Await resolve={fetchUserName}>
          {(userName) => <p>Welcome, {userName}!</p>}
        </Await>
      </Suspense>
    </div>
  );
}

<Form>

This built in component offers built-in onsubmit automatically submit content through action and loader, automatically handles file uploads and define your http method and it also offer pending state.

import { Form, useLoaderData } from "@remix-run/react";
import { json } from "@remix-run/node";

export const loader = async ({ request }) => {
  const url = new URL(request.url);
  const name = url.searchParams.get("name"); // Get query parameter for the GET form
  return json({ name });
};

export const action = async ({ request }) => {
  const formData = await request.formData();
  const file = formData.get("file");
  const name = formData.get("name");

  if (file) {
    // Handle file upload
    console.log(`Uploaded file: ${file.name}`);
  }

  if (name) {
    // Handle form submission
    return json({ message: `Hello, ${name}!` });
  }

  return json({ message: "No valid data received." });
};

export default function Index() {
  const { name } = useLoaderData();

  return (
    <div>
      <h1>Remix Form Examples</h1>

      {/* POST Form Example */}
      <section>
        <h2>Submit Your Name (POST)</h2>
        <Form method="post">
          <label>
            Name: <input type="text" name="name" />
          </label>
          <button type="submit">Submit</button>
        </Form>
      </section>

      {/* GET Form Example */}
      <section>
        <h2>Search User (GET)</h2>
        <Form method="get">
          <label>
            Name: <input type="text" name="name" />
          </label>
          <button type="submit">Search</button>
        </Form>
        {name && <p>Result: {name}</p>}
      </section>

      {/* File Upload Example */}
      <section>
        <h2>Upload a File</h2>
        <Form method="post" encType="multipart/form-data">
          <label>
            File: <input type="file" name="file" />
          </label>
          <button type="submit">Upload</button>
        </Form>
      </section>
    </div>
  );
}

<Link>

Its also pre-built in react as well as remix, extension of anchor tag.

import { Link } from "@remix-run/react";

<Link to="/dashboard">Dashboard</Link>;

export const link = () => {
return [ { rel:'canonical', herf:'/post/389327832' } ]
}

<Links>

This component is generally used only in root.tsx file as all link tag present under links component.

import { Links } from "@remix-run/react";

export const links = () => [
  { rel: 'preconnect', href: 'https://fonts.googleapis.com' },
  {
    rel: 'stylesheet',
    href: 'https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap',
  },
  {
    rel: 'stylesheet',
    href: 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-okaidia.min.css',
  },
  {
    rel: 'icon',
    type: "image/x-icon",
    href: './favicon.ico',
  },
]

export default function Root() {
  return (
    <html>
      <head>
        <Links />
      </head>
      <body></body>
    </html>
  );
}

<LiveReload>

This component generally connencts your app to Remix asset server and automatically renders the file content changed and save it in development environment. In production it renders null.

import { LiveReload } from "@remix-run/react";

export default function Root() {
  return (
    <html>
      <head />
      <body>
        <LiveReload />
      </body>
    </html>
  );
}

<Meta>

This component same does the links component as it renders all the meta tags under one roof.

import { Meta } from "@remix-run/react";

export default function Root() {
  return (
    <html>
      <head>
        <Meta />
      </head>
      <body></body>
    </html>
  );
}


export const meta = () => {
  return [
    { title: "New Remix App" },
    { name: "description", content: "Welcome to Remix!" },
  ];
};