Vercel
Vercelにデプロイするには、adapter-vercelを使用してください。
このアダプターは、adapter-autoを使用するとデフォルトでインストールされますが、プロジェクトに追加することで、Vercel固有のオプションを指定できます。
使い方
npm i -D @sveltejs/adapter-vercelでインストールし、svelte.config.jsにアダプターを追加します。
import function adapter(config?: Config): Adapteradapter from '@sveltejs/adapter-vercel';
export default {
kit: {
adapter: Adapter;
}
kit: {
adapter: Adapteradapter: function adapter(config?: Config): Adapteradapter({
// see below for options that can be set here
})
}
};デプロイ設定
Vercelにルートが関数としてどのようにデプロイされるかを制御するには、上記のオプションを使用するか、+server.js、+page(.server).js、+layout(.server).jsファイル内のexport const configを使用して、デプロイ設定を指定できます。
たとえば、アプリの一部をEdge Functionsとしてデプロイできます...
/** @type {import('@sveltejs/adapter-vercel').Config} */
export const const config: {
runtime: string;
}
config = {
runtime: stringruntime: 'edge'
};import type { type Config = (EdgeConfig | ServerlessConfig) & {
images?: ImagesConfig;
}
Config } from '@sveltejs/adapter-vercel';
export const const config: Configconfig: type Config = (EdgeConfig | ServerlessConfig) & {
images?: ImagesConfig;
}
Config = {
runtime: "edge"runtime: 'edge'
};...また、他の部分をServerless Functionsとしてデプロイできます。(レイアウト内でconfigを指定すると、すべての子ページに適用されることに注意してください)
/** @type {import('@sveltejs/adapter-vercel').Config} */
export const const config: {
runtime: string;
}
config = {
runtime: stringruntime: 'nodejs22.x'
};import type { type Config = (EdgeConfig | ServerlessConfig) & {
images?: ImagesConfig;
}
Config } from '@sveltejs/adapter-vercel';
export const const config: Configconfig: type Config = (EdgeConfig | ServerlessConfig) & {
images?: ImagesConfig;
}
Config = {
ServerlessConfig.runtime?: `nodejs${number}.x` | undefinedWhether to use Edge Functions ('edge') or Serverless Functions ('nodejs18.x', 'nodejs20.x' etc).
runtime: 'nodejs22.x'
};次のオプションは、すべての関数に適用されます。
runtime:'edge'、'nodejs18.x'、'nodejs20.x'、または'nodejs22.x'。デフォルトでは、アダプターはVercelダッシュボードでプロジェクトが使用するように設定されているNodeバージョンに対応する'nodejs<version>.x'を選択します。regions:エッジネットワークリージョンの配列(サーバーレス関数の場合はデフォルトで["iad1"])または、runtimeがedge(デフォルト)の場合は'all'。サーバーレス関数の複数のリージョンは、エンタープライズプランでのみサポートされていることに注意してください。split:trueの場合、ルートは個別の関数としてデプロイされます。splitがアダプターレベルでtrueに設定されている場合、すべてのルートが個別の関数としてデプロイされます。
さらに、次のオプションはエッジ関数に適用されます。
external:esbuildが関数をバンドルするときに外部として扱う依存関係の配列。これは、Nodeの外部では実行されないオプションの依存関係を除外する場合にのみ使用する必要があります。
そして、次のオプションはサーバーレス関数に適用されます。
memory:関数で使用できるメモリの量。デフォルトは1024Mbで、128Mbに減らすか、Proまたはエンタープライズアカウントで3008Mbまで64Mb刻みで増やすことができます。maxDuration:関数の最大実行時間。デフォルトは、Hobbyアカウントで10秒、Proで15秒、エンタープライズで900秒です。isr:後述するインクリメンタル静的再生成の設定。
関数が特定のリージョン内のデータにアクセスする必要がある場合は、最適なパフォーマンスを得るために、同じリージョン(またはその近く)にデプロイすることをお勧めします。
画像最適化
images設定を設定して、Vercelが画像をどのようにビルドするかを制御できます。詳細については、画像構成リファレンスを参照してください。例として、次のように設定できます。
import function adapter(config?: Config): Adapteradapter from '@sveltejs/adapter-vercel';
export default {
kit: {
adapter({ images: { sizes: [], 640: , 828: , 1200: , 1920: , 3840: } }: {
images: {
sizes: Iterable<any>;
640: any;
828: any;
1200: any;
1920: any;
3840: any;
};
}): any;
formats: string[];
minimumCacheTTL: number;
domains: string[];
}
kit: {
function adapter({ images: { sizes: [], 640: , 828: , 1200: , 1920: , 3840: } }: {
images: {
sizes: Iterable<any>;
640: any;
828: any;
1200: any;
1920: any;
3840: any;
};
}): any
adapter({
images: {
sizes: Iterable<any>;
640: any;
828: any;
1200: any;
1920: any;
3840: any;
}
images: {
sizes: Iterable<any>sizes: [640, 828, 1200, 1920, 3840],
formats: string[]formats: ['image/avif', 'image/webp'],
minimumCacheTTL: numberminimumCacheTTL: 300,
domains: string[]domains: ['example-app.vercel.app'],
}
})
}
};
インクリメンタル静的再生成
Vercelはインクリメンタル静的再生成(ISR)をサポートしており、事前にレンダリングされたコンテンツのパフォーマンスとコスト上の利点と、動的にレンダリングされたコンテンツの柔軟性を提供します。
ルートにISRを追加するには、configオブジェクトにisrプロパティを含めます。
import { import BYPASS_TOKENBYPASS_TOKEN } from '$env/static/private';
export const const config: {
isr: {
expiration: number;
bypassToken: any;
allowQuery: string[];
};
}
config = {
isr: {
expiration: number;
bypassToken: any;
allowQuery: string[];
}
isr: {
// Expiration time (in seconds) before the cached asset will be re-generated by invoking the Serverless Function.
// Setting the value to `false` means it will never expire.
expiration: numberexpiration: 60,
// Random token that can be provided in the URL to bypass the cached version of the asset, by requesting the asset
// with a __prerender_bypass=<token> cookie.
//
// Making a `GET` or `HEAD` request with `x-prerender-revalidate: <token>` will force the asset to be re-validated.
bypassToken: anybypassToken: import BYPASS_TOKENBYPASS_TOKEN,
// List of valid query parameters. Other parameters (such as utm tracking codes) will be ignored,
// ensuring that they do not result in content being regenerated unnecessarily
allowQuery: string[]allowQuery: ['search']
}
};expirationプロパティは必須です。他のすべてのプロパティはオプションです。
事前レンダリングされたページは、ISR構成を無視します。
環境変数
Vercelは、デプロイメント固有の環境変数のセットを利用可能にします。他の環境変数と同様に、これらは$env/static/privateと$env/dynamic/privateからアクセス可能で(場合によっては、後述します)、その公開対応物からはアクセスできません。クライアントからこれらの変数のいずれかにアクセスするには
import { import VERCEL_COMMIT_REFVERCEL_COMMIT_REF } from '$env/static/private';
/** @type {import('./$types').LayoutServerLoad} */
export function function load(): {
deploymentGitBranch: any;
}
load() {
return {
deploymentGitBranch: anydeploymentGitBranch: import VERCEL_COMMIT_REFVERCEL_COMMIT_REF
};
}import { import VERCEL_COMMIT_REFVERCEL_COMMIT_REF } from '$env/static/private';
import type { type LayoutServerLoad = (event: Kit.ServerLoadEvent<Record<string, any>, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>
type LayoutServerLoad = (event: Kit.ServerLoadEvent<Record<string, any>, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>
LayoutServerLoad } from './$types';
export const const load: LayoutServerLoadload: type LayoutServerLoad = (event: Kit.ServerLoadEvent<Record<string, any>, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>
type LayoutServerLoad = (event: Kit.ServerLoadEvent<Record<string, any>, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>
LayoutServerLoad = () => {
return {
deploymentGitBranch: anydeploymentGitBranch: import VERCEL_COMMIT_REFVERCEL_COMMIT_REF
};
};<script>
/** @type {{ data: import('./$types').LayoutServerData }} */
let { data } = $props();
</script>
<p>This staging environment was deployed from {data.deploymentGitBranch}.</p><script lang="ts">
import type { LayoutServerData } from './$types';
let { data }: { data: LayoutServerData } = $props();
</script>
<p>This staging environment was deployed from {data.deploymentGitBranch}.</p>これらの変数はすべてVercelでのビルド時にビルド時と実行時で変更されないため、$env/dynamic/privateではなく、変数を静的に置き換える$env/static/privateを使用することをお勧めします。これにより、不要なコードの削除などの最適化が可能になります。
スキュー保護
アプリの新しいバージョンがデプロイされると、以前のバージョンに属するアセットにアクセスできなくなる可能性があります。ユーザーがこのときにアプリをアクティブに使用している場合、ナビゲート時にエラーが発生する可能性があります。これはバージョン スキューとして知られています。SvelteKitは、バージョン スキューによって発生したエラーを検出し、アプリの最新バージョンを取得するためにハードリロードを行うことで、これを軽減しますが、これによりクライアント側の状態が失われます。(また、新しいバージョンがデプロイされたときにクライアントに通知するupdatedストアの値を監視することで、事前に軽減することもできます。)
スキュー保護は、クライアントのリクエストを元のデプロイメントにルーティングするVercelの機能です。ユーザーがアプリにアクセスすると、デプロイメントIDを含むCookieが設定され、スキュー保護がアクティブである限り、後続のリクエストはそのデプロイメントにルーティングされます。ページをリロードすると、最新のデプロイメントが取得されます。(updatedストアはこの動作から除外されているため、引き続き新しいデプロイメントを報告します。)有効にするには、Vercelのプロジェクト設定の[詳細]セクションにアクセスします。
Cookieベースのスキュー保護には1つの注意点があります。ユーザーが複数のタブでアプリの複数のバージョンを開いている場合、古いバージョンからのリクエストは新しいバージョンにルーティングされるため、SvelteKitの組み込みのスキュー保護にフォールバックされます。
注意点
Vercel関数
プロジェクトのルートにあるapiディレクトリにVercel関数が含まれている場合、/api/*へのリクエストはSvelteKitによって処理されません。代わりに、これらの関数をSvelteKitアプリでAPIルートとして実装する必要があります。JavaScript以外の言語を使用する必要がある場合は、SvelteKitアプリに/api/*ルートがないことを確認する必要があります。
Nodeバージョン
特定の日付より前に作成されたプロジェクトは、SvelteKitが現在必要とするNodeバージョンよりも古いバージョンを使用するようにデフォルト設定されている場合があります。プロジェクト設定でNodeバージョンを変更できます。
トラブルシューティング
ファイルシステムへのアクセス
エッジ関数ではfsを使用できません。
サーバーレス関数では使用できますが、ファイルがプロジェクトからデプロイメントにコピーされないため、期待どおりに動作しません。代わりに、$app/serverのread関数を使用してファイルにアクセスします。readは、エッジ関数としてデプロイされたルート内では機能しません(これは将来変更される可能性があります)。
または、問題のルートを事前レンダリングすることもできます。