This is will be long article because it a self note for deploying Sveltekit project (as node project) on IIS version 10.
For a while I searching thru the internet and asking in svelte discord (so good community , if you're svelter don't miss to join in) I found out it have little information about how to deploying Sveltekit on IIS , may be I've so many conditions and requirements to made Sveltekit project working on my IIS server.
Conditions and Requirements
running with one port and separate each project by sub-directory.
ex.
projectA ==>https://my.testsites.com:443/projectA
projectB ==>https://my.testsites.com:443/projectB
Need to be Server side rendering (SSR) which is Sveltekit project suppose to be.
Any form actions are not blocked by Cross-site Request Forgery (CSRF) protection of Sveltekit project.
Prerequisites
- express.js on sveltekit project
- node.js (recommend LTS version) on IIS server globally install
- some demo Sveltekit project, Let using Sveltekit demo project
- IIS Services -- how to install IIS
after install IIS
How to step by step
- run
npm i
in your sveltekit project folder - installing additional dependencies
- adapter-node for sveltekit
npm i -D @sveltejs/adapter-node
- dotenv
npm i dotenv
- adapter-node for sveltekit
- setup
.env
file in your root folder of your project and put this in your.env
file
ORIGIN=http://localhost:PORT_OF_SITES
while PORT_OF_SITES
will be your port number of IIS site you want to deploy to let say it is 443 then it will be
ORIGIN=http://localhost:443
this will be using after we have deploy Svletekit project to IIS and prevent CSRF blocked after any form actions
- In root folder of your project find
svelte.config.js
and adding adapter-node and set base path to made it support a sub-directory in Sveltekit, let change all code inside like this
import adapter from '@sveltejs/adapter-node';
export default {
kit: {
adapter: adapter(),
paths: {
relative: false,
base: '/NAME_OF_SUB-DIRECTORY'
}
}
};
while NAME_OF_SUB-DIRECTORY
will specifies where your app is served from and allows the app to live on a non-root path
ex. you want your site address like https://my.sites.com/svelteiis
then svelte.config.js
code will be like this
import adapter from '@sveltejs/adapter-node';
export default {
kit: {
adapter: adapter(),
paths: {
relative: false,
base: '/svelteiis'
}
}
};
- after we adding adapter-node and adding base path we need to prepend all root-relative links with the
base
value or they will point to the root of your domain, not yourbase
path (this is how the Sveltekit and browser work)
in src\routes\Header.svelte
, src\routes\about\+page.svelte
and src\routes\sverdle\+page.svelte
we will adding import { base } from '$app/paths';
in <script>
tag and adding every <a>
tag with {base}
ex. <a href="{base}/">Home</a>
, {base}/about">About</a>
- next we will build our project as a node project by using
npm run build
and let adapter-node handle it's job . . . . . after some times you will have abuild
folder appear in your root project like image below
- let change side to config our IIS , firstly open our IIS and on your left pane just opening till you seen
Default Web Site
just right click on it and clickexplore
like image below
-it will open a new window of file explorer with path C:\inetpub\wwwroot
(let note this as a wwwroot
folder) after that you can copy a build
folder that we has created earlier in our Sveltekit project folder and let changing it name form build
to a name of what your sub-directory you want that will match with base
path that we config earlier or it cause some issue on navigating to your site!
after this step your wwwroot
folder will be like image below
**you can deploy your project on new IIS site too by creating a new site in IIS and set physicals path to your deploy folder and bring your build
folder into there and following the step by changing build
folder name.
- next we need to copy 2 files form your root project folder, that is
.env
file andpackage.json
file and bring it to your deploying folder inwwwroot
and running justnpm i --omit=dev
in this folder to made node downloading only required dependencies after running npm creating newweb.config
file and adding this code into yourweb.config
file
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<webSocket enabled="false" />
<handlers>
<add name="iisnode" path="server.cjs" verb="*" modules="iisnode" />
</handlers>
<iisnode node_env="production" nodeProcessCommandLine="C:\Program Files\nodejs\node.exe" />
<rewrite>
<rules>
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^server.cjs\/debug[\/]?" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
</rule>
<rule name="StaticContent">
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="public{PATH_INFO}" />
</rule>
<rule name="DynamicContent">
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="server.cjs" />
</rule>
</rules>
<outboundRules>
<rule name="back">
<match serverVariable="RESPONSE_Location" pattern="(.*)/server.cjs" />
<action type="Rewrite" value="{R:1}" />
</rule>
</outboundRules>
</rewrite>
<defaultDocument>
<files>
<add value="server.cjs" />
</files>
</defaultDocument>
<security>
<requestFiltering>
<hiddenSegments>
<remove segment="bin" />
</hiddenSegments>
<requestLimits maxAllowedContentLength="4294967295" />
</requestFiltering>
</security>
<httpErrors existingResponse="PassThrough" />
</system.webServer>
</configuration>
after this config your Sveltekit deploy folder will be like a image below
- last but not least we need to have some JavaScript file that will be running after iisnode calling to our project , that made our project can adjust some environment setting
let create a new file name
server.cjs
or any other name but if you change the name you need to put that name into aweb.config
file from earlier (try search and replaceserver.cjs
with your new file's name inweb.config
) after creating aserver.cjs
file add this code below to your file
require('dotenv').config();
const express = require('express')
import('./handler.js')
.then((handler) => {
const app = express();
// Custom middleware to make routing case-insensitive
app.use((req, res, next) => {
const urlSegments = req.url.split('/');
urlSegments[1] = urlSegments[1].toLowerCase();
req.url = urlSegments.join('/');
next();
});
// let SvelteKit handle everything else, including serving prerendered pages and static assets
app.use(handler.handler);
app.listen(process.env.PORT, () => {
console.log(
'app start on port ' + process.env.PORT
);
});
}).catch((err) => console.error(err));
this will made your .env
file that you copying from earlier working as aspect and will set your origin of project to prevent CSRF protection from a form actions of the project itself and it will made your site can accessing with case insensitive url at a first sub-directory.
by the way you can disabled case insensitive by comment out below code in server.cjs
app.use((req, res, next) => {
const urlSegments = req.url.split('/');
urlSegments[1] = urlSegments[1].toLowerCase();
req.url = urlSegments.join('/');
next();
});
now inside the project folder in wwwroot
will look like this
after that you can try going to the site that you have deploy by go to
http://localhost/NAME_OF_SUB-DIRECTORY
or http://localhost:YOUR_IIS_PORT/NAME_OF_SUB-DIRECTORY
and finally you has achieved Sveltekit deploying on IIS !
If you has any question or suggestion on my walkthrough feel free to giving me a comment below. ;)
Thanks you
Have a nice day and keep coding
Top comments (0)