The Golang net/http
package has a FileServer()
method that serves static files like images, CSS, JavaScript, etc.
It takes the path of a folder that contains all those files you want to serve and returns an HTTP handler.
Register that handler using http.Handle()
method and your Go server will serve those files as static.
Serve Static Files From Go Server
We usually return HTML documents or JSON data as an API from a Golang server. But when it comes to serving static files, we need to register a file server handler.
Suppose you have a public
folder in your server that contains CSS, JavaScript, and images.
This is the file structure in our project:
- main.go
- /public
- /css
- style.css
- /js
- main.js
- images
- banner.jpg
To serve all these files from your server, you have to define a file server handler using the public
directory.
You have to call the http.FileServer()
method with the directory that contains your files.
package main
import (
"fmt"
"net/http"
)
func main() {
// Create a file server handler that serves static files from the "public" directory
staticDir := http.Dir("./public")
fileServer := http.FileServer(staticDir)
// Use the file server handler to handle requests for static files from "/static" route
http.Handle("/static/", http.StripPrefix("/static/", fileServer))
// Start the server on port 8000
fmt.Println("Server is running on port 8000")
http.ListenAndServe(":8000", nil)
}
I am calling the http.Dir()
method with the path of the public
directory. It represents the directory from which you want to serve your static files.
Next, call the http.FileServer()
method with the staticDir
returned from the http.Dir()
method. It will return the file server handler.
Finally, register the file server handler using http.Handle()
method. Here I am registering the handler for the "/static/" path.
But if you directly pass the fileServer handler to your http.Handle()
method, it won't work.
When you try to get the banner.jpg
file from the public
directory by hitting this /static/
handler, Go will try to find this file inside the ./static/public
directory which doesn't exist.
By default, Golang adds the Routh path with the Directory path while serving the static file. By calling http.StripPrefix()
method, you can remove /static
prefix from the directory path.
- Before calling
http.StripPrefix()
method -./static/public/images/banner.jpg
- After calling
http.StripPrefix()
method -./public/images/banner.jpg
Now if you visit http://localhost:8000/static/images/banner.jpg
URL, your server will return the image file from ./public/images/banner.jpg
path.
Server Static Files From Multiple Directories
It is also possible to serve static files from multiple directories. You just have to register a file server handler for each directory.
This is the file structure in our project:
- main.go
- /public
- /css
- style.css
- /js
- main.js
- uploads
- banner.jpg
The process is exactly the same. Call the http.Dir()
method with each directory path.
Pass the http.Dir
to the http.FileServer()
method to get the HTTP handler and register the handler for a specific route.
Don't forget to remove the route prefix from the file server handler using http.StripPrefix()
method before registering your handler.
package main
import (
"fmt"
"net/http"
)
func main() {
// Serving static files from the "public" directory
staticDir := http.Dir("./public")
fileServer := http.FileServer(staticDir)
http.Handle("/static/", http.StripPrefix("/static/", fileServer))
// Serving static files from the "uploads" directory
uploadsDir := http.Dir("./uploads")
uploadsFileServer := http.FileServer(uploadsDir)
http.Handle("/uploads/", http.StripPrefix("/uploads/", uploadsFileServer))
// Start the server on port 8000
fmt.Println("Server is running on port 8000")
http.ListenAndServe(":8000", nil)
}
I have public
and uploads
directories and I want to server static files from these 2 directories.
Therefore, I have registered public
and uploads
directories as file servers in /static/
and /uploads/
routes respectively.
- Visit
http://localhost:8000/static/js/main.js
URL to get the JavaScript file. - Visit
http://localhost:8000/uploads/banner.jpg
URL to get the image file.
Server a Static HTML Website From Golang
By registering a directory as a file server, you can also serve a static HTML website from your Golang server.
This is the file structure in our static HTML website:
- main.go
- /public
- /css
- style.css
- /js
- main.js
- /images
- banner.jpg
- index.html
- /about
- index.html
In our static HTML website, we have index.html
file inside the ./public
directory which represents the Home page and ./about/index.html
file which is our About page.
To serve this HTML website, create a file server handler using http.FileServer()
method and register the handler in the root ("/") route.
package main
import (
"fmt"
"net/http"
)
func main() {
// Serving static HTML website from the "public" directory
staticDir := http.Dir("./public")
fileServer := http.FileServer(staticDir)
http.Handle("/", fileServer)
// Start the server on port 8000
fmt.Println("Server is running on port 8000")
http.ListenAndServe(":8000", nil)
}
Here I am registering my file server handler in the "/" route because I want to serve the ./public/index.html
file if someone visits http://localhost:8000
If you don't define a specific route path in http.Handle()
method, you don't have to use the http.StripPrefix()
method.
- Visit
http://locahost:8000/about
to see the About page.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>About</title>
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<h1>About Page</h1>
<div class="banner">
<img src="/images/banner.jpg" alt="Banner image">
</div>
<script src="/js/main.js"></script>
</body>
</html>
You can also include CSS, JavaScript, and image files in your HTML files. The file server handler will also serve these files from the public
directory.
That's how you can set up your Golang server to serve static files for different purposes.