How to Serve Static Files in Golang Server With Examples

Robin
Updated on December 6, 2023

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.

Related Posts