Serving static files

I’m having issues with serving static files. How i can serve static files?

package main

import (

func getRoot(w http.ResponseWriter, r *http.Request) {
	fmt.Printf("got / request\n")
    http.ServeFile(w, r, "index.html");

func main() {
	if os.Args[1] == "run" {
        static := http.FileServer(http.Dir("./"))
	    http.Handle("/", static)

		http.HandleFunc("/", getRoot)

		err := http.ListenAndServe(":3000", nil)

		if errors.Is(err, http.ErrServerClosed) {
			fmt.Printf("server closed\n")
		} else if err != nil {
			fmt.Printf("error starting server: %s\n", err)

When I try to run your code, I get this panic:

panic: http: multiple registrations for /

goroutine 1 [running]:
net/http.(*ServeMux).Handle(0xe112c0, {0xc3e512, 0x1}, {0xcb2040?, 0xc6d040})
        C:/Program Files/Go/src/net/http/server.go:2478 +0x226
        C:/Program Files/Go/src/net/http/server.go:2515
        C:/Program Files/Go/src/net/http/server.go:2527
        C:/Users/Sean/go/src/ +0xcc
exit status 2

The first line says panic: http: multiple registrations for / and if I look at your code, line 18 registers the "/" path to be handled by the static function and line 20 registers "/" to be handled by the getRoot function. If I:

  1. Comment out either one of these functions,
  2. Create an index.html file,
  3. Execute go run . run
  4. Navigate to http://localhost:3000/

I get the content of my index.html file.


Just to add to @skillian’s answer: serving up index.html with your getRoot handler is redundant. http.FileServer will correctly serve up index.html when it sees a root path (and in fact redirects “/index.html” to “/”):

As a special case, the returned file server redirects any request ending in “/index.html” to the same path, without the final “index.html”.