Back to Top

How to integrate Odoo with ReactJS frontend

Updated 25 February 2026

Introduction

Odoo is no longer just a monolithic ERP with server-rendered views.

With its mature API layer and flexible authentication, Odoo can serve as a headless backend for modern frontends like React, Next.js, and mobile apps.

This guide explains a modern, tested approach to integrating Odoo 18 with a React frontend – focusing on scalability, performance, and production-ready best practices.

Why Use React with Odoo?

Using React as a frontend and Odoo as a backend provides:

  • Faster UI using client-side rendering or SSR
  • Complete control over UX/UI without QWeb limitations
  • Independent deployments of frontend and backend
  • Better performance for high-traffic apps like headless eCommerce

This architecture is commonly referred to as Odoo Headless.

Searching for an experienced
Odoo Company ?
Find out More

High-Level Architecture

  • React / Next.js Frontend
  • Vite Proxy (Dev) / Nginx (Prod)
  • JSON-RPC API Layer
  • Odoo Backend

The frontend never interacts with Odoo views or templates directly. All communication occurs via APIs.

API Options in Odoo

Odoo does not expose a standard REST API by default.

JSON-RPC (Native and Recommended)

  • Default protocol used by Odoo’s web client
  • Uses /jsonrpc or /web/dataset/call_kw
  • Session-based authentication (cookies)
  • Provides full access to all Odoo models
  • No third-party modules required

This guide uses the native JSON-RPC approach.

Modern Frontend Stack

LayerTechnology
FrameworkReact + Vite + TypeScript
StylingTailwind CSS
State ManagementReact Hooks / Context
HTTP ClientAxios
AuthenticationOdoo Session-Based Auth
Tech Stack

Step-by-Step Implementation

Step 1 – Create React App (Modern Setup)

Using Vite with TypeScript is recommended for structured Odoo model handling.

npm create vite@latest odoo-connect -- --template react-ts
cd odoo-connect
npm install axios
npm run dev

Step 2 – Tailwind CSS Setup

Install Dependencies

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

Configure tailwind.config.js

export default {
  content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
  theme: {
    extend: {
      colors: {
        primary: "#714B67",
      },
    },
  },
  plugins: [],
};

Step 3: Set up Env Variables

Create .env File

VITE_ODOO_BASE_URL=http://localhost:8069
VITE_ODOO_DB=your_database_name

Configure Proxy in vite.config.ts

import { defineConfig, loadEnv } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd(), "");
  return {
    plugins: [react()],
    server: {
      proxy: {
        "/web": {
          target: env.VITE_ODOO_BASE_URL,
          changeOrigin: true,
          secure: false,
        },
      },
    },
  };
});

This proxy routes API calls through Vite’s dev server, preventing CORS issues during development.

Step 4 – Create JSON-RPC API Layer

Create src/api/client.ts to centralize communication with Odoo.

import axios from "axios";
export const api = axios.create({
  baseURL: "/",
  headers: { "Content-Type": "application/json" },
  withCredentials: true,
});
export const odooCall = async <T>(
  model: string,
  method: string,
  args: any[] = [],
  kwargs: any = {}
) => {
  const response = await api.post("/web/dataset/call_kw", {
    jsonrpc: "2.0",
    method: "call",
    params: { model, method, args, kwargs },
    id: Math.floor(Math.random() * 1000000000),
  });
  if (response.data.error) {
    throw response.data.error;
  }
  return response.data.result as T;
};

This reusable helper keeps your API layer clean, maintainable, and scalable.

Step 5 – Authentication (Session-Based)

Odoo uses session-based authentication. Once logged in, the browser automatically manages cookies.

Login Example

const handleLogin = async (username: string, password: string) => {
  try {
    const response = await api.post("/web/session/authenticate", {
      jsonrpc: "2.0",
      params: {
        db: import.meta.env.VITE_ODOO_DB,
        login: username,
        password: password,
      },
    });

    const result = response.data.result;

    if (result && result.uid) {
      console.log("Logged in as", result.username);
      localStorage.setItem("odoo_session", JSON.stringify(result));
    }
  } catch (error) {
    console.error("Login Failed", error);
  }
};

Step 6 – Fetching Data & Images

Fetch Products

const fetchProducts = async () => {
  const products = await odooCall("product.product", "search_read", [], {
    fields: ["name", "list_price"],
    limit: 20,
  });

  return products;
};

Always request only the required fields and apply limits to improve performance.

Display Product Images

const getImageUrl = (id: number) =>
  `/web/image?model=product.product&id=${id}&field=image_128`;

<img src="{getImageUrl(product.id)}" alt="{product.name}">;

Use resized image fields like image_128 or image_256 to optimize loading speed.

Step 7 – Session Persistence

React state resets on refresh. Persist the session using localStorage.

const [session, setSession] = useState(() => {
  const saved = localStorage.getItem("odoo_session");
  return saved ? JSON.parse(saved) : null;
});

Logout

localStorage.removeItem("odoo_session");

Screenshots (Demo App)

Production Best Practices

Security

  • Always use HTTPS in production
  • Do not expose Odoo port 8069 publicly
  • Use Nginx or Apache as a reverse proxy
  • Configure CORS properly when using different domains

Performance

  • Request resized images (image_128, image_256)
  • Use limit and offset in search_read
  • Always specify required fields
  • Avoid fetching unnecessary relational fields

Conclusion

Integrating Odoo 18 with React using native JSON-RPC enables a scalable, secure, and upgrade-safe headless architecture.

By separating the frontend and backend, you gain full control over UX while leveraging Odoo’s powerful business logic and data management.

With a proper Vite proxy, session-based auth, a structured API layer, and Nginx in production – you can deploy high-performance apps without any third-party REST modules.

This approach is stable, future-proof, and fully suitable for enterprise-level implementations.

If you are planning to implement advanced headless solutions, explore the Webkul Odoo REST APIs for headless development services.

You can also check out our open-source Odoo React headless eCommerce app to accelerate your development process.

Webkul, an official Odoo partner and Odoo development company, offers custom module development, SaaS solutions, mobile apps, system integrations, and data migrations.

Thank you for reading! We hope this guide helps you confidently build modern headless applications powered by Odoo.

And that’s a wrap – you now have everything you need to integrate Odoo 18 with a modern React frontend.
Happy Coding!

. . .

Leave a Comment

Your email address will not be published. Required fields are marked*


Be the first to comment.

Back to Top

Message Sent!

If you have more details or questions, you can reply to the received confirmation email.

Back to Home