diff --git a/caddyhttp/templates/templates.go b/caddyhttp/templates/templates.go
index 91491f11573149a8af397b08949c7cc20d2fabb3..afc6fbe3bd3ade5ea67dc4d9faafbcaa0a7c1d6a 100644
--- a/caddyhttp/templates/templates.go
+++ b/caddyhttp/templates/templates.go
@@ -4,6 +4,7 @@ package templates
 
 import (
 	"bytes"
+	"mime"
 	"net/http"
 	"os"
 	"path"
@@ -62,6 +63,16 @@ func (t Templates) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error
 					return http.StatusInternalServerError, err
 				}
 
+				// If Content-Type isn't set here, http.ResponseWriter.Write
+				// will set it according to response body. But other middleware
+				// such as gzip can modify response body, then Content-Type
+				// detected by http.ResponseWriter.Write is wrong.
+				ctype := mime.TypeByExtension(ext)
+				if ctype == "" {
+					ctype = http.DetectContentType(buf.Bytes())
+				}
+				w.Header().Set("Content-Type", ctype)
+
 				templateInfo, err := os.Stat(templatePath)
 				if err == nil {
 					// add the Last-Modified header if we were able to read the stamp