Migrate to Chi router and add Norwegian Devigo demo
Major improvements: - Replace Gorilla Mux with Chi v5 router for better performance and cleaner code - Fix CSS/JS MIME type issues that prevented proper asset loading - Add built-in CORS middleware replacing manual OPTIONS handlers - Simplify routing with nested route syntax - Update URL parameter extraction from mux.Vars to chi.URLParam New Devigo demo: - Add production Norwegian sales training website (devigo.no) - Real-world Hugo-generated content with TailwindCSS - 39 insertr-enhanced elements for comprehensive CMS testing - Demonstrates international language support and B2B use cases - Fixed asset paths for localhost serving compatibility Technical benefits: - Automatic MIME type detection for static files - Reduced code complexity with built-in middleware - Better performance with lighter dependency stack - Production-ready CORS handling
This commit is contained in:
77
cmd/serve.go
77
cmd/serve.go
@@ -8,7 +8,9 @@ import (
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
"github.com/go-chi/cors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
@@ -120,55 +122,54 @@ func runServe(cmd *cobra.Command, args []string) {
|
||||
contentHandler := api.NewContentHandler(database, authService)
|
||||
contentHandler.SetSiteManager(siteManager)
|
||||
|
||||
// Setup router
|
||||
router := mux.NewRouter()
|
||||
// Setup Chi router
|
||||
router := chi.NewRouter()
|
||||
|
||||
// Add middleware
|
||||
router.Use(api.CORSMiddleware)
|
||||
router.Use(api.LoggingMiddleware)
|
||||
// Add Chi middleware
|
||||
router.Use(middleware.Logger)
|
||||
router.Use(middleware.Recoverer)
|
||||
router.Use(cors.Handler(cors.Options{
|
||||
AllowedOrigins: []string{"*"}, // In dev mode, allow all origins
|
||||
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
|
||||
AllowedHeaders: []string{"*"},
|
||||
ExposedHeaders: []string{"Link"},
|
||||
AllowCredentials: true,
|
||||
MaxAge: 300, // Maximum value not ignored by any of major browsers
|
||||
}))
|
||||
router.Use(api.ContentTypeMiddleware)
|
||||
|
||||
// Health check endpoint
|
||||
router.HandleFunc("/health", api.HealthMiddleware())
|
||||
|
||||
// API routes
|
||||
apiRouter := router.PathPrefix("/api").Subrouter()
|
||||
|
||||
// Content endpoints
|
||||
contentRouter := apiRouter.PathPrefix("/content").Subrouter()
|
||||
contentRouter.HandleFunc("/bulk", contentHandler.GetBulkContent).Methods("GET")
|
||||
contentRouter.HandleFunc("/{id}", contentHandler.GetContent).Methods("GET")
|
||||
|
||||
contentRouter.HandleFunc("", contentHandler.GetAllContent).Methods("GET")
|
||||
contentRouter.HandleFunc("", contentHandler.CreateContent).Methods("POST")
|
||||
|
||||
// Version control endpoints
|
||||
contentRouter.HandleFunc("/{id}/versions", contentHandler.GetContentVersions).Methods("GET")
|
||||
contentRouter.HandleFunc("/{id}/rollback", contentHandler.RollbackContent).Methods("POST")
|
||||
|
||||
// Site enhancement endpoint
|
||||
apiRouter.HandleFunc("/enhance", contentHandler.EnhanceSite).Methods("POST")
|
||||
router.Get("/health", api.HealthMiddleware())
|
||||
|
||||
// Static library serving (for demo sites)
|
||||
router.HandleFunc("/insertr.js", contentHandler.ServeInsertrJS).Methods("GET")
|
||||
router.Get("/insertr.js", contentHandler.ServeInsertrJS)
|
||||
|
||||
// API routes
|
||||
router.Route("/api", func(apiRouter chi.Router) {
|
||||
// Site enhancement endpoint
|
||||
apiRouter.Post("/enhance", contentHandler.EnhanceSite)
|
||||
|
||||
// Content endpoints
|
||||
apiRouter.Route("/content", func(contentRouter chi.Router) {
|
||||
contentRouter.Get("/bulk", contentHandler.GetBulkContent)
|
||||
contentRouter.Get("/{id}", contentHandler.GetContent)
|
||||
contentRouter.Get("/", contentHandler.GetAllContent)
|
||||
contentRouter.Post("/", contentHandler.CreateContent)
|
||||
|
||||
// Version control endpoints
|
||||
contentRouter.Get("/{id}/versions", contentHandler.GetContentVersions)
|
||||
contentRouter.Post("/{id}/rollback", contentHandler.RollbackContent)
|
||||
})
|
||||
})
|
||||
|
||||
// Static site serving - serve registered sites at /sites/{site_id}
|
||||
siteRouter := router.PathPrefix("/sites").Subrouter()
|
||||
// This fixes the MIME type issues with Chi's FileServer
|
||||
for siteID, siteConfig := range siteManager.GetAllSites() {
|
||||
log.Printf("📁 Serving site %s from %s at /sites/%s/", siteID, siteConfig.Path, siteID)
|
||||
siteRouter.PathPrefix("/" + siteID + "/").Handler(
|
||||
http.StripPrefix("/sites/"+siteID+"/",
|
||||
http.FileServer(http.Dir(siteConfig.Path))))
|
||||
fileServer := http.FileServer(http.Dir(siteConfig.Path))
|
||||
router.Handle("/sites/"+siteID+"/*", http.StripPrefix("/sites/"+siteID+"/", fileServer))
|
||||
}
|
||||
|
||||
// Handle CORS preflight requests explicitly
|
||||
contentRouter.HandleFunc("/{id}", api.CORSPreflightHandler).Methods("OPTIONS")
|
||||
contentRouter.HandleFunc("", api.CORSPreflightHandler).Methods("OPTIONS")
|
||||
contentRouter.HandleFunc("/bulk", api.CORSPreflightHandler).Methods("OPTIONS")
|
||||
contentRouter.HandleFunc("/{id}/versions", api.CORSPreflightHandler).Methods("OPTIONS")
|
||||
contentRouter.HandleFunc("/{id}/rollback", api.CORSPreflightHandler).Methods("OPTIONS")
|
||||
apiRouter.HandleFunc("/enhance", api.CORSPreflightHandler).Methods("OPTIONS")
|
||||
|
||||
// Start server
|
||||
addr := fmt.Sprintf(":%d", port)
|
||||
mode := "production"
|
||||
|
||||
Reference in New Issue
Block a user