The Problem
Let’s say that you create a simple web application with the Nim Heroku Buildpack.
Project structure:
├── nim_heroku.nimble
├── Procfile
├── src
│   ├── nim_heroku
│   ├── nim_heroku.nim
│   └── views
│       └── general.nim
├── static_dir
│   ├── favicon.ico
│   └── style.css
└── tags
3 directories, 8 files
Bin file (src/nim_heroku.nim):
import jester, asyncdispatch, os, strutils
import views/general
var settings = newSettings()
if existsEnv("PORT"):
  settings.port = Port(parseInt(getEnv("PORT")))
settings.staticDir = "./static_dir"
routes:
  get "/":
    resp renderMain()
runForever()
View (src/views/general.nim):
#? stdtmpl(subsChar = '$', metaChar = '#')
#
#proc renderMain*(): string =
##  result = ""
<!DOCTYPE html>
<html>
  <head>
    <title>Nim Heroku Test</title>
    <link rel="stylesheet" href="https://unpkg.com/modern-css-reset/dist/reset.min.css" />
    <link rel="stylesheet" type="text/css" href="style.css">
    <link rel="shortcut icon" href="favicon.ico">
  </head>
  <body>
    <div class="center text-center">
      <div class="[ flow ]">
        <p>Hello World</p>
        <p>This is a test</p>
      </div>
    </div>
  </body>
</html>
#end proc
We load a css file and a favicon in the HTML head.
That works fine in local development. But when you deploy to Heroku, you won’t see those files with a HTTP status error code of 403.
The Solution
You can bundle assets like CSS or JavaScript with nimassets.
- Install nimassets locally - nimble install nimassets
- Use your terminal to create the assets file: - nimassets -d=static_dir -o= src/views/assetsfile.nim
- Import the assets file into your view. Add the CSS file to your HTML with the - <style>tag.- #? stdtmpl(subsChar = '$', metaChar = '#') #import assetsfile # #let css = assetsFile.getAsset("static_dir/style.css") # #proc renderMain*(): string = ## result = "" <!DOCTYPE html> <html> <head> <title>Nim Heroku Test</title> <link rel="stylesheet" href="https://unpkg.com/modern-css-reset/dist/reset.min.css" /> <style type="text/css"> ${css} </style> <link rel="shortcut icon" href="favicon.ico"> </head> <body> <div class="center text-center"> <div class="[ flow ]"> <p>Hello World</p> <p>This is a test</p> </div> </div> </body> </html> #end proc
- Serve the favicon icon directly with Jester. You have to find the file with - os.walkdir(- src/views/static_assets.nim):- import os, sequtils, re var filepaths: seq[string] for kind, path in walkdir("./static_dir/"): filepaths.add(path) let icoFile = filter(filepaths, proc (x: string): bool = contains(x, re".ico"))[0] let ico* = readFile(icoFile)
- Create a route for serving the favicon: - import jester, asyncdispatch, os, strutils import views/general, views/static_assets var settings = newSettings() settings.staticDir = "./static_dir" if existsEnv("PORT"): settings.port = Port(parseInt(getEnv("PORT"))) template corsResp(code, message: untyped): untyped = mixin resp resp code, {"Access-Control-Allow-Origin": "*"}, message routes: get "/": corsResp(Http200, renderMain()) get "/favicon.ico": corsResp(Http200, ico) runForever()
- Push to Heroku and it should work. 
Project structure:
.
├── nim_heroku.nimble
├── Procfile
├── src
│   ├── nim_heroku
│   ├── nim_heroku.nim
│   └── views
│       ├── assetsfile.nim
│       ├── general.nim
│       ├── static_assets
│       └── static_assets.nim
├── static_dir
│   ├── favicon.ico
│   └── style.css
└── tags
3 directories, 11 files