ข้ามไปยังเนื้อหา

Load Functions

ทุกแอปที่จริงจังต้องดึงข้อมูลก่อน render หน้า React ecosystem แก้ปัญหานี้มาหลายแบบตลอดหลายปี: react-router loader, Next.js getServerSideProps, Next.js App Router server component SvelteKit รวมทุกแบบเป็น convention เดียวที่คาดเดาได้: ฟังก์ชัน load ที่ export จากไฟล์ข้าง page ของคุณ

รันตัวอย่างนี้ในโปรเจกต์ SvelteKit (npx sv create)

react-router v6.4+ แนะนำฟังก์ชัน loader — async function ที่รันก่อน route จะ render load ของ +page.js ใน SvelteKit คือแนวคิดเดียวกัน แต่ไฟล์อยู่ข้าง page แทนที่จะฝังใน route config object

React (react-router)
// react-router v6.4 — route config
import { createBrowserRouter } from 'react-router-dom';
import { useLoaderData } from 'react-router-dom';
async function postLoader({ params }) {
const res = await fetch('/api/posts/' + params.id);
return res.json();
}
function PostPage() {
const post = useLoaderData();
return <h1>{post.title}</h1>;
}
const router = createBrowserRouter([
{
path: '/posts/:id',
element: <PostPage />,
loader: postLoader,
},
]);
SvelteKit +page.js
// src/routes/posts/[id]/+page.js
export async function load({ params, fetch }) {
const res = await fetch('/api/posts/' + params.id);
const post = await res.json();
return { post };
}

load ของ +page.js รันทั้ง บน server (request แรก) และบน client (การนำทางของ SvelteKit) ซึ่งหมายความว่าคุณได้ server-rendered HTML ตอนโหลดครั้งแรก และการเปลี่ยนหน้าฝั่ง client ที่รวดเร็วในการนำทางครั้งต่อไป — ได้มาฟรี ๆ

สิ่งที่ load return จะเข้าถึงได้ในชื่อ data ผ่าน \$props():

src/routes/posts/[id]/+page.svelte
<script>
let { data } = $props();
// data.post is the object returned from load()
</script>
<h1>{data.post.title}</h1>
<p>{data.post.body}</p>

TypeScript: import PageLoad (สำหรับ +page.js) หรือ PageServerLoad (สำหรับ +page.server.js) จากไฟล์ ./$types ที่สร้างอัตโนมัติ:

// +page.js (universal)
import type { PageLoad } from './$types';
export const load: PageLoad = async ({ params, fetch }) => {
const post = await fetch('/api/posts/' + params.id).then(r => r.json());
return { post };
};

getServerSideProps คือ data loader ฝั่ง server เท่านั้นของ Next.js Pages Router — รันบน server อย่างเดียว เข้าถึงฐานข้อมูลและ secret ได้ แล้วส่งข้อมูลเป็น props ให้ page component +page.server.js ของ SvelteKit คือ equivalent โดยตรง

Next.js (getServerSideProps)
// Next.js Pages Router — pages/posts/[id].tsx
export async function getServerSideProps({ params }) {
const post = await db.post.findUnique({
where: { id: Number(params.id) },
});
return { props: { post } };
}
export default function PostPage({ post }) {
return <h1>{post.title}</h1>;
}
SvelteKit +page.server.js
// src/routes/posts/[id]/+page.server.js
import { db } from '$lib/db';
export async function load({ params, cookies }) {
const post = await db.post.findUnique({
where: { id: Number(params.id) },
});
return { post };
}

เวอร์ชัน +page.server.js:

  • รัน บน server เท่านั้น — ปลอดภัยสำหรับ DB query, secret, private env var
  • รับ cookies เพิ่มเติมจาก params, fetch, และ url
  • return plain object; SvelteKit serialise แล้วส่งให้ client เป็น data

ทั้ง +page.js และ +page.server.js ควรแจ้งว่า resource หาไม่เจอด้วย helper error() จาก @sveltejs/kit แทนที่จะ throw plain object เอง — SvelteKit จะ render หน้า +error.svelte ที่ถูกต้องให้ ตั้งแต่ SvelteKit 2 เป็นต้นมา error() จะ throw ให้เองภายใน จึงเรียกโดยไม่ต้องมี throw นำหน้า:

src/routes/blog/[slug]/+page.server.js
import { db } from '$lib/db';
import { error } from '@sveltejs/kit';
export async function load({ params }) {
const post = await db.post.findUnique({ where: { slug: params.slug } });
if (!post) error(404, 'Not found');
return { post };
}
+page.js (universal)+page.server.js (server-only)
Runs on serverYes (initial request)Yes (always)
Runs on clientYes (navigations)No
Access cookiesNoYes
Access DB directlyNot recommendedYes
Access private env varsNoYes
fetch is availableYes (enhanced)Yes (enhanced)

วิธีตัดสินใจแบบไว ตามสถานการณ์:

สถานการณ์ไฟล์ที่ควรใช้
เรียก public REST API+page.js
ต้องการ fetch ทั้งบน server (SSR) และ client (navigation)+page.js
Query ฐานข้อมูลโดยตรง+page.server.js
อ่าน cookie หรือ session+page.server.js
ใช้ API key ที่เป็น secret+page.server.js

หลักคิดง่าย ๆ: ถ้าไม่อยากให้โค้ดดังกล่าวปรากฏใน browser bundle ให้ใช้ +page.server.js

ทั้ง universal และ server load function รับ argument หลักชุดเดียวกัน:

// +page.js or +page.server.js
export async function load({ params, fetch, url, cookies }) {
// params — route parameters, e.g. params.slug
// fetch — SvelteKit-enhanced fetch (sets cookies, handles relative URLs)
// url — the current URL as a URL object
// cookies — (server only) read/write cookies
}
+page.js และ +page.server.js ใน SvelteKit ต่างกันอย่างไร?
SvelteKit page component รับข้อมูลที่ load() return กลับมาได้อย่างไร?
argument ของ load() ตัวไหนที่มีเฉพาะใน +page.server.js ไม่มีใน +page.js?