Serve static files in Gin web application

Serve static files in Gin web application
Serve static files in Gin web application

To continue with Gin-Gonic web application development, let’s talk about how to serve static files in Gin web application.

Create a Gin project

First thing to do is to initialize a Gin project, you can follow my following commands or create in your own way:

$ mkdir gin-serve-staticfiles

$ cd gin-serve-staticfiles

$ go mod init

$ go get

$ touch main.go

then, put this basic starting code into main.go:

package main

import ""

func main() {
	router := gin.Default()


Make sure this Gin web application is working by running it and confirm on the browser:

$ go run main.go

[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /*filepath                -->*RouterGroup).createStaticHandler.func1 (3 handlers)
[GIN-debug] HEAD   /*filepath                -->*RouterGroup).createStaticHandler.func1 (3 handlers)
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check for details.
[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[GIN-debug] Listening and serving HTTP on :8080

Prepare static files

Let’s create a static directory which contains all static files to be serve, ex. JS, CSS…

From the root of project, create a new directory named public , and create two sub-directories inside public named css, js.

Create a new file inside public/css named styles.css with following style definition:

#currentTime {
    font-weight: bold;
    font-size: 20px;

Create a new file inside public/js named time.js with following sample code:

function getCurrentTimeString() {
    const now = new Date();
    const y = now.getFullYear();
    const m = now.getMonth();
    const d = now.getDate();
    const h = now.getHours();
    const mi = now.getMinutes();
    const s = now.getSeconds();
    return y + '-' + m + '-' + d + ' ' + h + ':' + m + ':' + s;
function updateCurrentTime() {
    const txtTime = document.getElementById('currentTime');
    txtTime.innerText = getCurrentTimeString()

setInterval(updateCurrentTime, 1000);

Create a new file index.html under public directory with following template:

<!doctype html>
<html lang="en">
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title> - Serve static files in Gin web application</title>
    <link rel="stylesheet" href="/css/styles.css">

<h1>Serve static files in Gin web application</h1>
<p>Current time: <span id="currentTime"></span> </p>

<script src="/js/time.js"></script>

Alright, let’s move on to the next step.

Serve static contents

To serve static contents in Gin web application, we will use the method Static() for the job. It has following definition:

func (group *RouterGroup) Static(relativePath, root string) IRoutes

The first parameter is to determine the base path where all static files would be served from.

The second parameter is to specify the path to the directory where files would be used to serve for the web app.

For example: if you have a directory on the system /tmp/static/ that contains several files like hello.js, styles.css … and want them to be served on the web with base path /public then the final path to access from browser is : HOST/public/hello.js

Since we already created a public directory in previous step, we will use it and serve it from the root URL /:

package main

import ""

func main() {
	router := gin.Default()

	router.Static("/", "./public")

Run the code and visit the site in the browser at , it should show the content from public/index.html

Serve static files in Gin-gonic framework
Serve static files in Gin-gonic framework

The public/css/styles.css and public/js/time.js are loaded and applied to the template as well.

If you check the Gin server log, you can see how static files are served:

[GIN] 2022/06/19 - 13:05:35 | 200 |    1.130291ms |             ::1 | GET      "/"
[GIN] 2022/06/19 - 13:05:35 | 200 |    4.143083ms |             ::1 | GET      "/js/time.js"
[GIN] 2022/06/19 - 13:05:35 | 200 |     340.708µs |             ::1 | GET      "/css/styles.css"


That’s how you serve static files in Gin web application.

Have fun!