This package contains an adapter for Sveltekit that will make your project output deployable to IIS.
pnpm add -D sveltekit-adapter-iis
#or
npm i sveltekit-adapter-iis --save-dev
#or
yarn add sveltekit-adapter-iis --dev
svelte.config.js
file replace default adapter with IISAdapter
import { vitePreprocess } from '@sveltejs/kit/vite'
import IISAdapter from 'sveltekit-adapter-iis'
/** @type {import('@sveltejs/kit').Config} */
const config = {
preprocess: vitePreprocess(),
kit: {
version: {
pollInterval: 300000,
},
adapter: IISAdapter({
// the hostname/port that the site will be hosted on in IIS.
// can be changed later in web.config
origin: 'http://localhost:80XX',
// ... other options
}),
},
}
export default config
pnpm build
#or
npm run build
You should try to bundle all your dependencies as dev dependencies so that you can skip this step however not all dependencies play nice. In this case you can install just the production dependencies using your preferred package manager.
npm
npm install --omit-dev
pnpm
pnpm install --P
yarn
yarn install --production=true
bun
bun install --production
IISRewrite
module and iisnode installed1 . In IIS Manager add a new Website: Sites -> Add Website...
Physical Path
to <your project>/.svelte-kit/adapter-iis
.C:/inetpub/<your project>
<your project>/.svelte-kit/adapter-iis
into C:/inetpub/<your project>
Sites -> Add Website...
Physical Path
to C:/inetpub/<your project>
.This is not a complete guide, but it should help.
localhost
without a portC:\ProgramData\Microsoft\Windows\Start Menu\Programs\Administrative Tools
Internet Information Services (IIS) Manager
%windir%\system32\inetsrv\InetMgr.exe
English x64
iisnode-full-vx.x.x-x64.msi
Read/Write
instead of Read Only
(More information needed)iisNodeOptions.loggingEnabled
to true
in the adapter optionsiisNodeOptions.logDirectory
node.exe
to override this set iisNodeOptions.overrideNodeExePath
.
const config = {
//...
kit: {
adapter: IISAdapter({
iisNodeOptions: {
nodeProcessCommandLine: 'C:\\Program Files\\nodejs\\node.exe', // or whatever the path is
},
}),
},
}
EBUSY
fs error.
adapter-iis
dir for IIS_USER or Everyone to allow allconsole.log
, try using console.warn
- it will show up in stderr
logs without stopping the server.https://
protocol, and have not set up SSL certificates in IIS, it will fail due to 'Cannot provide secure connection'/virtual-images/image1.png
instead of https://localhost:XXXX/virtual-images/image1.png
http
instead of https
protocol
keyhttps
once deploying to productionorigin
option, or it is mismatched// svelte.config.js
const config = {
//...
kit: {
adapter: IISAdapter({
origin: 'http://localhost:8010', // or whatever the site's origin is when you deploy it using IIS
}),
},
}
This sets it in web.config
during building.
Detailed errors
in IIS for the site.Error Pages
Edit Feature Settings...
under the Actions menu on the rightDetailed Errors
.
This will allow Sveltekit to handle errors itself.
outputWhitelist
This adapter also provides outputWhitelist
in options. This is useful when you need some extra directories on server for the app to function. You can do the following:
Use rollup-plugin-copy
to copy the files
// vite.config.ts
import { resolve } from 'node:path'
import { defineConfig, normalizePath } from 'vite'
import copy from 'rollup-plugin-copy'
// your define config does not need to be a function, i think
// i did it like this to make sure thecopy plugin only runs when building
export default defineConfig(({ command }) => {
const config = {
// ...
plugins: [],
}
if (command === 'build') {
const copyPlugin = copy({
targets: [
{
// some files you want to copy over
src: [
'db/*.htaccess',
'db/schema.json',
'db/*SCINDEX.json',
'db/vtmeta.yml',
],
dest: normalizePath(resolve('.svelte-kit', 'adapter-iis', 'db')),
},
],
hook: 'writeBundle',
})
config.plugins.push(copyPlugin)
}
return config
})
set the outputWhitelist
// svelte.config.js
const config = {
//...
kit: {
adapter: IISAdapter({
// origin, ...
outputWhitelist: ['db'],
}),
},
}
Now, when building, .svelte-kit/adapter-iis/db
should get preserved instead of being deleted
You might want to use the IIS feature 'Virtual Directory', where it maps a real directory onto a route.
To make sure sveltekit doesn't block this with a 404, modify externalRoutes
option in the adapter config:
// svelte.config.js
const config = {
//...
kit: {
adapter: IISAdapter({
// origin, ...
externalRoutes: ['cdn', 'images', 'viewer'],
}),
},
}
Then add some virtual directories that map to cdn
, images
, and viewer
.
Re-build the app, and these routes will be taken into account in the generated web.config
file.
/healthcheck
routeBy default, since IIS can be quite tricky to set up, the adapter adds a simple /healthcheck
route, which responds with 'ok'
This is useful if you want to determine that the node server is running, but your main site isn't loading for whatever reson.
The route can be turned off setting the healthcheckRoute
adapter option to false
. (A re-build is needed to take effect.)
When providing environment variables through a .env
file, the adapter will also look for any .env.{stage}
files in order to create web.{stage}.config
transformation files in .svelte-kit/adapter-iis
. These transformation files can later be used to perform XML Transformation steps in your CI/CD pipelines based on which stage is being deployed to.
Read more about XML Transformations here: XML Transformation in Azure Pipelines
// svelte.config.js
const config = {
//...
kit: {
adapter: IISAdapter({
// origin, ...
redirectToHttps: true,
}),
},
}
By setting the option redirectToHttps
to true
, a URL Rewrite rule is applied to the web.config
file that redirect all non-HTTPS request to HTTPS.
httpErrors
By default IIS will take control of HTTP errors and show the default IIS [STATUS].htm
for each status. If you want the SvelteKit application to handle all HTTP errors, you can specify httpErrors.existingResponse
with PassThrough
to let the application handle the errors.
// svelte.config.js
const config = {
//...
kit: {
adapter: IISAdapter({
// origin, ...
httpErrors: {
existingResponse: 'PassThrough',
},
}),
},
}
Note that this only works when served from the root of a domain.
So you can serve it from www.mysvelteapp.com
or sub.mysvelteapp.com
but it will not work from www.mysvelteapp.com/subfolder
. Unfortunately this is due to how routing works with sveltekit. Adding the base
property to your sveltekit config causes all of the routes to have that appended so you end up with the app living on www.mysevelteapp.com/subfolder/subfolder
.
This adapter wraps adapter-node
from @sveltejs/kit
and uses node:http
as the web server. It outputs a web.config file that rewrites incoming requests to the node:http
server.
Contributions are welcome! Please open an issue or submit a PR if you would like to help out with this project!