The $app/server module provides server-only utilities, including asset reading and remote function creation.
read
Read the contents of an imported asset from the filesystem.
Read an imported asset file.Parameters:
asset (string) - The imported asset path
Returns: Response object with file contentsSince: 2.4.0
import { read } from '$app/server';
import somefile from './somefile.txt';
const asset = read(somefile);
const text = await asset.text();
Reading Different File Types
import { read } from '$app/server';
import dataFile from './data.json';
import imageFile from './image.png';
// Read JSON
const jsonResponse = read(dataFile);
const data = await jsonResponse.json();
// Read binary data
const imageResponse = read(imageFile);
const blob = await imageResponse.blob();
Ensure your adapter supports the read implementation. Modern adapters include this functionality.
getRequestEvent
Get the current request event.
Retrieve the current RequestEvent.Returns: RequestEvent | undefined
import { getRequestEvent } from '$app/server';
const event = getRequestEvent();
if (event) {
console.log('Request URL:', event.url);
console.log('Headers:', event.request.headers);
}
Remote Functions
Remote functions allow you to call server-side code from the browser with type safety and automatic serialization.
query
Create a remote query for data fetching.
Creates a remote query that can be called from the browser.Parameters:
schema (StandardSchema | ‘unchecked’) - Optional validation schema
fn (function) - The server function to execute
Returns: RemoteQueryFunctionSince: 2.27
No Arguments
// routes/+page.server.js
import { query } from '$app/server';
export const getServerTime = query(() => {
return new Date().toISOString();
});
<!-- routes/+page.svelte -->
<script>
import { getServerTime } from './+page.server.js';
const time = getServerTime();
</script>
{#await time}
Loading...
{:then value}
Server time: {value}
{/await}
With Validation Schema
import { query } from '$app/server';
import { z } from 'zod';
const getUserSchema = z.object({
id: z.string()
});
export const getUser = query(getUserSchema, async ({ id }) => {
const user = await db.users.findById(id);
return user;
});
<script>
import { getUser } from './+page.server.js';
const user = getUser({ id: '123' });
</script>
{#await user}
Loading user...
{:then data}
<h1>{data.name}</h1>
{/await}
import { query } from '$app/server';
export const searchPosts = query('unchecked', async (searchTerm) => {
const posts = await db.posts.search(searchTerm);
return posts;
});
Query Methods
Force refresh the query data
Manually set the query value
Create a query with overridden options (client-side only)
command
Create a remote command for mutations.
Creates a remote command that executes server-side mutations.Parameters:
schema (StandardSchema | ‘unchecked’) - Optional validation schema
fn (function) - The server function to execute
Returns: RemoteCommandSince: 2.27
// routes/+page.server.js
import { command } from '$app/server';
import { z } from 'zod';
const updateUserSchema = z.object({
id: z.string(),
name: z.string()
});
export const updateUser = command(updateUserSchema, async ({ id, name }) => {
await db.users.update(id, { name });
return { success: true };
});
<!-- routes/+page.svelte -->
<script>
import { updateUser } from './+page.server.js';
async function handleSubmit() {
const result = await updateUser({ id: '123', name: 'John' });
console.log(result); // { success: true }
}
</script>
<button onclick={handleSubmit}>Update User</button>
Commands can only be called from mutative request methods (POST, PUT, PATCH, DELETE) or during client-side execution.
Create a remote form for progressive enhancement.
Creates a form object that can be spread onto a <form> element.Parameters:
schema (StandardSchema | ‘unchecked’) - Optional validation schema
fn (function) - The server function to execute
Returns: RemoteFormSince: 2.27
// routes/+page.server.js
import { form } from '$app/server';
import { z } from 'zod';
const contactSchema = z.object({
name: z.string().min(1),
email: z.string().email(),
message: z.string().min(10)
});
export const contactForm = form(contactSchema, async (data, issue) => {
// Validation errors are automatically handled
await sendEmail(data);
return { success: true };
});
<script>
import { contactForm } from './+page.server.js';
</script>
<form {...contactForm.enhance()}>
<input name="name" />
<input name="email" type="email" />
<textarea name="message"></textarea>
<button>Send</button>
</form>
prerender
Create a remote function that can be prerendered.
Creates a remote function that works during prerendering.Parameters:
schema (StandardSchema | ‘unchecked’) - Optional validation schema
fn (function) - The server function to execute
options (object) - Configuration options
Returns: RemotePrerenderFunctionSince: 2.27
Options
Generator function that yields inputs for prerendering
Whether the function can be called with dynamic inputs
import { prerender } from '$app/server';
import { z } from 'zod';
const getPostSchema = z.object({
slug: z.string()
});
export const getPost = prerender(
getPostSchema,
async ({ slug }) => {
const post = await db.posts.findBySlug(slug);
return post;
},
{
async *inputs() {
const posts = await db.posts.findAll();
for (const post of posts) {
yield { slug: post.slug };
}
},
dynamic: true
}
);
Usage Examples
Type-Safe Data Fetching
// routes/blog/+page.server.js
import { query } from '$app/server';
import { z } from 'zod';
const paginationSchema = z.object({
page: z.number().min(1).default(1),
limit: z.number().min(1).max(100).default(10)
});
export const getPosts = query(paginationSchema, async ({ page, limit }) => {
const posts = await db.posts.paginate({ page, limit });
return posts;
});
import { form } from '$app/server';
import { z } from 'zod';
const registerSchema = z.object({
email: z.string().email(),
password: z.string().min(8)
});
export const register = form(registerSchema, async (data, issue) => {
const existingUser = await db.users.findByEmail(data.email);
if (existingUser) {
issue('email', 'Email already registered');
return;
}
const user = await db.users.create(data);
return { userId: user.id };
});
Optimistic Updates with Commands
<script>
import { updatePost } from './+page.server.js';
let post = $state({ title: 'Original' });
async function save() {
const originalTitle = post.title;
// Optimistic update
post.title = 'Saving...';
try {
await updatePost({ id: post.id, title: originalTitle });
post.title = originalTitle;
} catch (error) {
// Revert on error
post.title = originalTitle;
}
}
</script>