Skip to main content

React

  1. Make sure your Reboot application is running
    source ./.venv/bin/activate
    rbt dev run
  2. Setup your frontend folder
    mkdir web && cd web
  3. Create Vite project
    npm create vite@latest . -- --template react-ts
  4. Install @reboot-dev/reboot-react
    npm install @reboot-dev/reboot-react
  5. Add RebootClientProvider to src/main.tsx
    // ./src/main.tsx
    import { RebootClientProvider } from "@reboot-dev/reboot-react";
    // ...
    // Matching the URL that `rbt dev run` prints out.
    const url = "http://localhost:9991";
    // ...
    <RebootClientProvider url={url}>
    <App />
    </RebootClientProvider>
    // ...
  6. Generate React API files

    Add the following line to your existing .rbtrc file:

    generate --react=web/src/api

    In the terminal running rbt dev run you'll see that the change is detected and the React code is generated.

  7. Replace exiting code in src/App.tsx
    // ./src/App.tsx
    import { useState } from "react";
    import { useHello } from "./api/hello/v1/hello_rbt_react";
    // TODO: import "./App.css";

    const App = () => {
    const [message, setMessage] = useState("Hello, Reboot!");

    const { useMessages, send } = useHello({ id: "reboot-hello" });
    const { response } = useMessages();

    const handleSend = async () => {
    if (message.trim()) {
    await send({ message });
    setMessage("");
    }
    };

    return (
    <div className="app-container">
    <h3 className="app-title">This is Reboot 🎉</h3>

    <div className="messages-container">
    {response?.messages.map((msg, index) => (
    <div key={index} className="message">{msg}</div>
    ))}
    {/* TODO: render pending messages optimistically. */}
    </div>

    <div className="input-container">
    <input
    value={message}
    onChange={(e) => setMessage(e.target.value)}
    onKeyDown={(e) => e.key === "Enter" && handleSend()}
    placeholder="Type your message here..."
    className="message-input"
    />
    <button onClick={handleSend} className="send-button">
    Send
    </button>
    </div>
    </div>
    );
    };

    export default App;
  8. Add styling (optional)
    /* ./src/App.css */
    .app-container {
    max-width: 500px;
    margin: 50px auto;
    padding: 20px;
    border: 1px solid #ddd;
    border-radius: 8px;
    font-family: Arial, sans-serif;
    }

    .app-title {
    text-align: center;
    font-weight: normal;
    margin-bottom: 20px;
    }

    .messages-container {
    margin-bottom: 20px;
    max-height: 300px;
    overflow-y: auto;
    }

    .message {
    background-color: #e3f2fd;
    padding: 8px 12px;
    margin: 4px 0;
    border-radius: 12px;
    word-wrap: break-word;
    color: black;
    }

    .pending-message {
    background-color: #fff3cd;
    padding: 8px 12px;
    margin: 4px 0;
    border-radius: 12px;
    word-wrap: break-word;
    opacity: 0.8;
    }

    .input-container {
    display: flex;
    gap: 8px;
    }

    .message-input {
    padding: 10px;
    flex: 1;
    border: 1px solid #ddd;
    border-radius: 20px;
    outline: none;
    }

    .message-input:focus {
    border-color: #007bff;
    }

    .send-button {
    padding: 10px 16px;
    background-color: #007bff;
    color: white;
    border: none;
    border-radius: 20px;
    cursor: pointer;
    }

    .send-button:hover {
    background-color: #0056b3;
    }

    Then replace this line in your App component:

    // TODO: import "./App.css";

    With:

    import "./App.css";
  9. Start your React app
    npm run dev
  10. Test your app

    View your app at http://localhost:3000 🎉. Try opening your app in multiple browser tabs!

  11. Add optimistic updates (optional)

    Replace this line in your App component:

    {/* TODO: render pending messages optimistically. */}

    With this code:

    {send.pending.map(({ request: { message } }, index) => (
    <div key={`pending-${index}`} className="pending-message">
    {message} (sending...)
    </div>
    ))}

    This will show messages immediately when you click Send, even before the backend confirms they've been processed. Try it out by making your backend sleep for a few seconds in the send method!

Next steps​

Well done! You made it! Check out these links to continue your exploration: