Static Content
Static content in Pode can be used by either placing your static files within the /public
directory, or by defining custom static routes. You can also specify default pages, such as index.html
, for when users navigate to root folders.
Caching is supported on static content.
Public Directory
You can place static files within the /public
directory at the root of your server, which serves as the default location for static content. When a request is made for a file, Pode will automatically check this designated static directory first, and if the file is found, it will be returned to the requester.
For example, if you have a logic.js
at /public/scripts/logic.js
. The following request would return the file's content:
Invoke-WebRequest -Uri http://localhost:8080/scripts/logic.js
Or, you can reference the file in a view like:
<script type="text/javascript" src="/scripts/logic.js"></script>
Changing the Default Folders
Usually, the Default Folders are located under the RootPath specified by Start-PodeServer -RootPath <path>
.
But if you need to relocate this directory, you can do so programmatically using the Set-PodeStaticFolder
function within your server script or specify a different location in the server.psd1
configuration file under the Server.DefaultFolders
property. When a file request is made, Pode will automatically check this designated static directory first, and if the file is found, it will be returned to the requester.
Here is an example:
- Using
Set-PodeStaticFolder
Set-PodeDefaultFolder -Type 'Public' -Path 'c:\custom\public'
Set-PodeDefaultFolder -Type 'Views' -Path 'd:\shared\views'
Set-PodeDefaultFolder -Type 'Errors' -Path 'e:\logs\errors'
- Using
server.psd1
configuration file
@{
# For more information https://badgerati.github.io/Pode/Tutorials/Configuration/
Server = @{
# Any other properties you need in your application
DefaultFolders = @{
Public = 'c:\custom\public'
Views = 'd:\shared\views'
Errors = 'e:\logs\errors'
}
}
}
Static Routes
The following is an example of using the Add-PodeStaticRoute
function to define a route to some static content directory; this tells Pode where to get static files for certain routes. This example will define a static route for /assets
, and will point the route at the internal directory path of ./content/assets
:
Start-PodeServer {
Add-PodeEndpoint -Address * -Port 8080 -Protocol Http
Add-PodeStaticRoute -Path '/assets' -Source './content/assets'
}
The following request will retrieve an image from the ./content/assets/images
directory:
Invoke-WebRequest -Uri 'http://localhost:8080/assets/images/icon.png' -Method Get
Middleware
Anything placed within your server's /public
directory will always be public static content. However, if you define custom static routes via Add-PodeStaticRoute
, then you can also supply middleware - including authentication.
Custom static routes follow a similar flow to normal routes, and any query string; payloads; cookies; etc, will all be parsed - allowing you to run any route-specific middleware before the static content is returned.
Middleware works the same as on normal Routes, so there's nothing extra you need to do. Any global middleware that you've defined will also work on static routes as well.
Default Pages
For static content, Pode also supports returning default pages when a root static content directory is requested. The inbuilt default pages are:
index.html
index.htm
default.html
default.htm
These pages are checked in order, and if one is found then its content is returned. Using the above static route, if the ./content/assets/home
directory contained an index.html
page, then the following request would return the content for the index.html
page:
Invoke-WebRequest -Uri 'http://localhost:8080/assets/images/home' -Method Get
The default pages can be configured in two ways; either by using the -Defaults
parameter on the Add-PodeStaticRoute
function, or by setting them in the server.psd1
configuration file. To set the defaults to be only a home.html
page, both ways would work as follows:
Defaults Parameter
Add-PodeStaticRoute -Path '/assets' -Source './content/assets' -Defaults @('index.html')
Configuration File
@{
Web = @{
Static = @{
Defaults = @('home.html')
}
}
}
The only difference is, if you have multiple static routes, setting any default pages in the server.psd1
file will apply to all static routes. Any default pages set using the -Default
parameter will have a higher precedence than the server.psd1
file.
Caching
Having web pages send requests to your Pode server for all static content every time can be quite a strain on the server. To help the server, you can enable static content caching, which will inform users' browsers to cache files (ie *.css
and *.js
) for so many seconds - stopping the browser from re-requesting it from your server each time.
By default, caching is disabled and can be enabled and controlled using the server.psd1
configuration file.
To enable caching, with a default cache time of 1hr, you do:
@{
Web = @{
Static = @{
Cache = @{
Enable = $true
}
}
}
}
If you wish to set a max cache time of 30mins, then you would use the MaxAge
property - setting it to 1800secs
:
@{
Web = @{
Static = @{
Cache = @{
Enable = $true
MaxAge = 1800
}
}
}
}
Include/Exclude
Sometimes you don't want all static content to be cached, maybe you want *.exe
files to always be re-requested? This is possible using the Include
and Exclude
properties in the server.psd1
.
Let's say you do want to exclude all *.exe
files from being cached:
@{
Web = @{
Static = @{
Cache = @{
Enable = $true
Exclude = @(
"*.exe"
)
}
}
}
}
Or, you could set up some static routes called /assets
and /images
, and you want everything on /images
to be cached, but only *.js
files to be cached on /assets
:
@{
Web = @{
Static = @{
Cache = @{
Enable = $true
Include = @(
"/images/*",
"/assets/*.js"
)
}
}
}
}
Downloadable
Normally content accessed on a static route is rendered on the browser, but you can set the route to flag the files for downloading instead. If you set the -DownloadOnly
switch on the Add-PodeStaticRoute` function, then accessing files on this route in a browser will cause them to be downloaded instead of rendered:
Start-PodeServer {
Add-PodeEndpoint -Address * -Port 8080 -Protocol Http
Add-PodeStaticRoute -Path '/assets' -Source './content/assets' -DownloadOnly
}
When a static route is set as downloadable, then -Defaults
and caching are not used.
File Browsing
This feature allows the use of a static route as an HTML file browser. If you set the -FileBrowser
switch on the Add-PodeStaticRoute
function, the route will show the folder content whenever it is invoked.
Start-PodeServer -ScriptBlock {
Add-PodeEndpoint -Address localhost -Port 8080 -Protocol Http
Add-PodeStaticRoute -Path '/' -Source './content/assets' -FileBrowser
Add-PodeStaticRoute -Path '/download' -Source './content/newassets' -DownloadOnly -FileBrowser
}
When used with -DownloadOnly
, the browser downloads any file selected instead of rendering. The folders are rendered and not downloaded.
Static Routes order
By default, Static routes are processed before any other route. There will be situations where you want normal routes to have priority over static ones. For example, you have to hide or make some computation to a file or a folder before returning the result.
Start-PodeServer -ScriptBlock {
Add-PodeRoute -Method Get -Path '/LICENSE.txt' -ScriptBlock {
$value = @'
Don't kid me. Nobody will believe that you want to read this legal nonsense.
I want to be kind; this is a summary of the content:
Nothing to report :D
'@
Write-PodeTextResponse -Value $value
}
Add-PodeStaticRoute -Path '/' -Source "./content" -FileBrowser
}
To change the default behaviour, you can use the Web.Static.ValidateLast
property in the server.psd1
configuration file, setting the value to $True.
This will ensure that any static route is evaluated after any other route.