How to serve static files using Vapor?

Vapor folder structure from Docs:

VaporApp
├── Package.swift
├── Resources
│   ├── Views
│   │   └── hello.leaf
├── Public
│   ├── images (images resources)
│   ├── styles (css resources)
└── Sources
    └── ...

Any files in the Public folder will be served by default if no routes have been registered that conflict with the file name.

For example, if you have a file Public/foo.png and the following main.swift file:

import Vapor

let drop = Droplet()

drop.get("welcome") { request in
    return "Hello, world"
}

drop.serve()

A request to localhost/welcome would return "Hello, world" and a request to localhost/foo.png would return foo.png.

If this is not working properly, it's likely that your working directory is not configured properly. This can happen if you are running your project from Xcode or you are running it from the command line from a folder that is not the root directory of the project.

To fix Xcode, go to Schemes > App > Edit Scheme > Run > Options > Working Directory > [x] Use Custom Working Directory and make sure the directory is set to the root of your project (where the Package.swift resides).

Xcode working directory

To fix when running from the command line, make sure you are running the application from the root directory. i.e., the run command should look something like .build/debug/App since the .build folder is located in the root directory.


For me, it was uncommenting this line in configure.swift:

middlewares.use(FileMiddleware.self) // Serves files from `Public` directory

In addition to the answer with FileMiddleware, sometimes one needs to serve a specific file instead of the whole Public directory, that's where using request.fileio.streamFile could help:

app.get("file") { (request: Request) in
  // stream the file
  request.eventLoop.makeSucceededFuture(
    request.fileio.streamFile(at: "/your/filepath")
  )
}

Tags:

Swift

Vapor