การตั้งค่าไฟล์ .htaccess บน web server ( ที่ไม่มีรองรับ NodeJS มีแต่ PHP ) เพื่อแก้ปัญหา Route ของ React Application

เมื่อเรา แต่ต้องการ upload ขึ้น host ซึ่งอาจเป็น shared host ธรรมดาเช่น hostgator หรือ godaddy เป็นต้นซึ่งปัญหาที่เจอ คือ เมื่อเราสร้าง route โดยใช้ browser router  หาก ผู้ใช้เข้ามาตาม path ที่เรากำหนดไว้ในครั้งแรกจะไม่สามารถเข้าได้ ผู้ใช้ต้องเข้าเข้าจากหน้าแรกก่อน

ในบทความนี้ จะแสดงวิธีแก้ปัญหา การใช้งาน BrowserRouter ของ react กับการ upload ขึ้น shared host ธรรมดา

รับเขียนโปรแกรม React



กรณีที่พัฒนา react โดยใช้ create-react-app  และ สมมุติว่าเรามี code ใน folder src ดังนี้ 

( ในตัวอย่างนี้ใช้ react-router-dom version 6  )

ไฟล์ master_page.js

import { useNavigate } from "react-router-dom";

const MasterPage=(props)=>{

    const navigate=useNavigate();

    return (<div>

        <div>
            <button onClick={event=>{ navigate("/page1") }} >Page1</button>
            <button onClick={event=>{ navigate("/page2") }} >Page2</button>
        </div>

        <hr />
        {props.children}

    </div>);

}

export default MasterPage;

ไฟล์ page1.js

import MasterPage from "./master_page";

const Page1=()=>{
    return <MasterPage>
        <h1>This is Page1 --- </h1>
    </MasterPage>
}

export default Page1;

ไฟล์ page2.js

import MasterPage from "./master_page";

const Page2=()=>{

    return <MasterPage>
        <h1>This is Page2 --- </h1>
    </MasterPage>
}

export default Page2;

ไฟล์ app.js

import Page1 from "./page1";
import Page2 from "./page2";

import {Routes, Route, BrowserRouter} from "react-router-dom";

function App() {
  return (
   <>
    <BrowserRouter>
        <Routes>

          <Route index  element={<Page1 />} />
          <Route path="page1"  element={<Page1 />} />
          <Route path="page2"  element={<Page2 />} />
         
        </Routes>
      </BrowserRouter>
   </>
  );
}

export default App;

จาก Code ดังกล่าว จะเห็นว่าเราสร้าง Route ของหน้าเว็บได้แก่ /page1 และ /page2 

และเมื่อเราทำการ build โดยใช้คำสั่ง npm run build แล้ว จะได้ folder ชื่อ build 

( โดยกรณีนี้ก่อน build ให้ กำหนด homepage ในไฟล์ package.json เพื่อให้ใช้ได้กับทุก domain )


เมื่อ รันคำสั่ง npm run build แล้ว ใน folder project จะมี folder build เพิ่มขึ้นมาซึ่งเราจะนำไฟล์ใน folder build นี้ upload ขึ้นไปไว้ที่ host


ปัญหาคือเมื่อเราใช้ BrowserRouter เราไม่สามารถเข้าผ่าน http://domain.com/page2 โดยตรงได้ จะต้องผ่าน http://domain.com/ คือหน้าแรกก่อนแล้วกด link ไป Page2 ถึงเข้า Page2 ได้เราสามารถกำหนดไฟล์ .htaccess และ Upload ไปที่ server ( Folder ที่เก็บไฟล์เว็บ ) เพื่อแก้ปัญหานี้ได้ ดังนี้

RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule . /index.html [L]

เพื่อระบุว่าหากเข้ามาใน path ที่ไม่มีอยู่ให้เรียกไฟล์ index.html