Skip to Content

Building a Simple App with Next.js and Ruby on Rails: A Beginner's Guide


This tutorial will guide you through building a basic web application that demonstrates communication between a Next.js frontend and a Ruby on Rails API backend. This is perfect for beginners to understand how modern web applications handle frontend-backend communication.


Prerequisites

  • Basic knowledge of JavaScript/React
  • Basic understanding of Ruby on Rails
  • Node.js and npm installed
  • Ruby and Rails installed
  • A code editor (VS Code recommended)


Project Structure

simple_app/
├── simple-app-frontend/  (Next.js)
└── simple-app-backend/   (Rails API)


Part 1: Setting Up the Backend (Rails API)

Create a new Rails API:

rails new simple-app-backend --api
cd simple-app-backend


Add CORS to your Gemfile:

gem 'rack-cors'


Install dependencies:

bundle install


Configure CORS in config/initializers/cors.rb:

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'http://localhost:3000'
    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end


Generate the API controller:

rails generate controller api/v1/Data index


Create a simple endpoint (app/controllers/api/v1/data_controller.rb):

class Api::V1::DataController < ApplicationController
  def index
    render json: { message: "Hello from Rails API!" }
  end
end


Set up routes in config/routes.rb:

Rails.application.routes.draw do
  namespace :api do
    namespace :v1 do
      get 'data', to: 'data#index'
    end
  end
end


Part 2: Setting Up the Frontend (Next.js)

If you haven’t installed Next.js yet, you can follow this guide: How to Install Next.js.

Create a Next.js application:

npx create-next-app@latest simple-app-frontend


Answer the prompts:

  • Would you like to use TypeScript? → No
  • Would you like to use ESLint? → Yes
  • Would you like to use Tailwind CSS? → Yes
  • Would you like to use src/ directory? → Yes
  • Would you like to use App Router? → Yes
  • Would you like to use Turbopack? → No
  • Would you like to customize the default import alias? → No


Go to the frontend directory:

cd simple-app-frontend


Update src/app/page.js:

'use client';
import { useState, useEffect } from 'react';

export default function Home() {
  const [message, setMessage] = useState('Loading...');

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch('http://localhost:3001/api/v1/data');
        const data = await response.json();
        setMessage(data.message);
      } catch (error) {
        console.error('Error:', error);
        setMessage('Error loading data');
      }
    };

    fetchData();
  }, []);

  return (
    <main className="flex min-h-screen flex-col items-center p-24">
      <div className="text-center">
        <h1 className="text-4xl font-bold mb-4">Simple App</h1>
        <p className="text-xl">{message}</p>
      </div>
    </main>
  );
}


Part 3: Running Your Application

Start the Rails server:

# In simple-app-backend directory
rails server -p 3001


Start the Next.js development server:

# In simple-app-frontend directory
npm run dev


Visit http://localhost:3000 in your browser to see your app in action.


Understanding How It Works

Frontend (Next.js)

  1. Page Load:
    • Shows initial "Loading..." state
    • Runs useEffect hook after mounting
    • Makes API request to Rails backend
  2. Component Structure:
    • 'use client' enables client-side features
    • useState manages message state
    • useEffect handles API communication

Backend (Rails)

  1. Request Handling:
    • Receives request at /api/v1/data
    • Returns JSON response
    • CORS allows frontend access


Communication Flow

Browser (localhost:3000)
       ↓
Next.js Frontend
       ↓
Rails API (localhost:3001)
       ↓
JSON Response
       ↓
Update UI


Common Issues and Solutions

  1. CORS Errors:
    • Check CORS configuration in Rails
    • Verify frontend URL in CORS settings
    • Ensure Rails server is running on port 3001
  2. Connection Issues:
    • Confirm both servers are running
    • Check port numbers
    • Verify API endpoint URL

Top Gems Every Ruby on Rails Developer Should Know in 2025