File Structure

After running npm run build, Vite emits a production-ready static bundle to the dist/ folder. The core entry points of the source are shown below.


index.html (root entry – replaces app/layout.tsx)
    
<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <link rel="icon" type="image/svg+xml" href="/assets/imgs/template/logo/favicon.svg" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Orisa - Multi-purpose React Template</title>

        <!-- Google Fonts: DM Sans -->
        <link rel="preconnect" href="https://fonts.googleapis.com" />
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
        <link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,100..1000;1,9..40,100..1000&display=swap" rel="stylesheet" />

        <!-- Template CSS -->
        <link rel="stylesheet" href="/assets/css/vendors/bootstrap.min.css" />
        <link rel="stylesheet" href="/assets/css/vendors/swiper-bundle.min.css" />
        <link rel="stylesheet" href="/assets/css/vendors/nice-select.css" />
        <link rel="stylesheet" href="/assets/css/vendors/magnific-popup.css" />
        <link rel="stylesheet" href="/assets/css/vendors/odometer.css" />
        <link rel="stylesheet" href="/assets/css/vendors/spacing.css" />
        <link rel="stylesheet" href="/assets/css/vendors/font-awesome-pro.css" />
        <link rel="stylesheet" href="/assets/css/main.css" />

        <style>
            :root { --at-ff-body: "DM Sans", sans-serif; }
            body { font-family: var(--at-ff-body); }
        </style>

        <!-- Theme init: set data-theme before first paint -->
        <script src="/scripts/theme-init.js"></script>
    </head>
    <body>
        <div class="px-blur-bottom"></div>
        <div id="root"></div>
        <script type="module" src="/src/main.tsx"></script>
    </body>
</html>
    

src/main.tsx (app bootstrap)
    
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { RouterProvider } from "react-router-dom";

import { router } from "@/router";
import PageLoader from "@/pages/PageLoader";

function App() {
    return (
        <>
            <PageLoader />
            <RouterProvider router={router} />
        </>
    );
}

createRoot(document.getElementById("root")!).render(
    <StrictMode>
        <App />
    </StrictMode>
);
    

src/router.tsx (route table – replaces App Router)
    
import { createBrowserRouter } from "react-router-dom";
import NotFound from "@/pages/NotFound";
import Home from "@/pages/Home";
import About1 from "@/pages/About1";
import Index2 from "@/pages/Index2";
// ...one import per route

export const router = createBrowserRouter([
    { path: "/",                  element: <Home /> },
    { path: "/about-1",           element: <About1 /> },
    { path: "/index-2",           element: <Index2 /> },
    // ...35+ routes total
    { path: "*",                  element: <NotFound /> },
]);
    

src/components/layout/Layout.tsx
    
import { MobileMenuCloneProvider } from "@/components/layout/MobileMenuCloneContext";
import BackToTop from "@/components/elements/BackToTopServer";
import ParallaxSceneEffect from "@/components/effects/ParallaxSceneEffect";
import Footer1 from "@/components/layout/footer/Footer1";
import Footer2 from "@/components/layout/footer/Footer2";
import Footer3 from "@/components/layout/footer/Footer3";
import Footer4 from "@/components/layout/footer/Footer4";
import Footer5 from "@/components/layout/footer/Footer5";
import Header1 from "@/components/layout/header/Header1";
import Header2 from "@/components/layout/header/Header2";
import Header3 from "@/components/layout/header/Header3";
import Header4 from "@/components/layout/header/Header4";
import Header5 from "@/components/layout/header/Header5";
import ServerEffects from "@/components/layout/ServerEffects";

const HEADER_COMPONENTS = { 1: Header1, 2: Header2, 3: Header3, 4: Header4, 5: Header5 } as const;
const FOOTER_COMPONENTS = { 1: Footer1, 2: Footer2, 3: Footer3, 4: Footer4, 5: Footer5 } as const;

function Header({ style }: { style?: number }) {
    if (!style) return <Header1 />;
    const C = HEADER_COMPONENTS[style as keyof typeof HEADER_COMPONENTS];
    return C ? <C /> : <Header1 />;
}

function Footer({ style }: { style?: number }) {
    if (!style) return <Footer1 />;
    const C = FOOTER_COMPONENTS[style as keyof typeof FOOTER_COMPONENTS];
    return C ? <C /> : <Footer1 />;
}

interface LayoutProps {
    children?: React.ReactNode;
    headerStyle?: number;
    footerStyle?: number;
}

export default function Layout({ children, headerStyle, footerStyle }: LayoutProps) {
    return (
        <MobileMenuCloneProvider>
            <ServerEffects />
            <div id="top" />
            <Header style={headerStyle} />
            <div id="smooth-wrapper">
                <div id="smooth-content" className="z-index-3">
                    <main className="bg-neutral-0">{children}</main>
                    {footerStyle !== 2 && <Footer style={footerStyle} />}
                </div>
                {footerStyle === 2 && <Footer style={footerStyle} />}
            </div>
            <ParallaxSceneEffect />
            <BackToTop />
        </MobileMenuCloneProvider>
    );
}
    

Next.js → React compatibility shims

Three tiny wrappers let every page/section from the Next.js source keep the same JSX without a single attribute change. Only the import paths are rewritten.

  • src/components/common/Image.tsx — drop-in replacement for next/image, renders a plain <img>.
  • src/components/common/Link.tsx — drop-in replacement for next/link, wraps React Router's Link and falls back to <a> for external / mailto: / # hrefs.
  • src/util/dynamic.tsx — drop-in replacement for next/dynamic, powered by React.lazy + Suspense.

Dependencies
    
        {
            "name": "orisa-react",
            "private": true,
            "version": "1.0.0",
            "type": "module",
            "scripts": {
                "dev": "vite",
                "build": "tsc -b && vite build",
                "preview": "vite preview",
                "lint": "eslint ."
            },
            "dependencies": {
                "bootstrap": "^5.3.3",
                "gsap": "^3.12.7",
                "isotope-layout": "^3.0.6",
                "react": "^19.0.0",
                "react-dom": "^19.0.0",
                "react-fast-marquee": "^1.6.5",
                "react-router-dom": "^7.0.0",
                "split-text": "^1.0.0",
                "swiper": "^11.2.5",
                "wowjs": "^1.1.3"
            },
            "devDependencies": {
                "@types/bootstrap": "^5.2.10",
                "@types/isotope-layout": "^3.0.14",
                "@types/node": "^22.10.0",
                "@types/react": "^19.0.0",
                "@types/react-dom": "^19.0.0",
                "@vitejs/plugin-react": "^4.3.4",
                "typescript": "^5.7.0",
                "vite": "^6.0.0"
            }
        }