Vercel
Vercelにデプロイするには、adapter-vercel
を使用してください。
このアダプターは、adapter-auto
を使用するとデフォルトでインストールされますが、プロジェクトに追加することで、Vercel固有のオプションを指定できます。
使い方
npm i -D @sveltejs/adapter-vercel
でインストールし、svelte.config.js
にアダプターを追加します。
import function adapter(config?: Config): Adapter
adapter from '@sveltejs/adapter-vercel';
export default {
kit: {
adapter: Adapter;
}
kit: {
adapter: Adapter
adapter: function adapter(config?: Config): Adapter
adapter({
// 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: string
runtime: 'edge'
};
import type { type Config = (EdgeConfig | ServerlessConfig) & {
images?: ImagesConfig;
}
Config } from '@sveltejs/adapter-vercel';
export const const config: Config
config: 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: string
runtime: 'nodejs22.x'
};
import type { type Config = (EdgeConfig | ServerlessConfig) & {
images?: ImagesConfig;
}
Config } from '@sveltejs/adapter-vercel';
export const const config: Config
config: type Config = (EdgeConfig | ServerlessConfig) & {
images?: ImagesConfig;
}
Config = {
ServerlessConfig.runtime?: `nodejs${number}.x` | undefined
Whether 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
:関数で使用できるメモリの量。デフォルトは1024
Mbで、128
Mbに減らすか、Proまたはエンタープライズアカウントで3008
Mbまで64Mb刻みで増やすことができます。maxDuration
:関数の最大実行時間。デフォルトは、Hobbyアカウントで10
秒、Proで15
秒、エンタープライズで900
秒です。isr
:後述するインクリメンタル静的再生成の設定。
関数が特定のリージョン内のデータにアクセスする必要がある場合は、最適なパフォーマンスを得るために、同じリージョン(またはその近く)にデプロイすることをお勧めします。
画像最適化
images
設定を設定して、Vercelが画像をどのようにビルドするかを制御できます。詳細については、画像構成リファレンスを参照してください。例として、次のように設定できます。
import function adapter(config?: Config): Adapter
adapter 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: number
minimumCacheTTL: 300,
domains: string[]
domains: ['example-app.vercel.app'],
}
})
}
};
インクリメンタル静的再生成
Vercelはインクリメンタル静的再生成(ISR)をサポートしており、事前にレンダリングされたコンテンツのパフォーマンスとコスト上の利点と、動的にレンダリングされたコンテンツの柔軟性を提供します。
ルートにISRを追加するには、config
オブジェクトにisr
プロパティを含めます。
import { import BYPASS_TOKEN
BYPASS_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: number
expiration: 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: any
bypassToken: import BYPASS_TOKEN
BYPASS_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_REF
VERCEL_COMMIT_REF } from '$env/static/private';
/** @type {import('./$types').LayoutServerLoad} */
export function function load(): {
deploymentGitBranch: any;
}
load() {
return {
deploymentGitBranch: any
deploymentGitBranch: import VERCEL_COMMIT_REF
VERCEL_COMMIT_REF
};
}
import { import VERCEL_COMMIT_REF
VERCEL_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: LayoutServerLoad
load: 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: any
deploymentGitBranch: import VERCEL_COMMIT_REF
VERCEL_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
は、エッジ関数としてデプロイされたルート内では機能しません(これは将来変更される可能性があります)。
または、問題のルートを事前レンダリングすることもできます。