Add a general SPA fallback instead of an explicit per-route list
Direct hits on client-side routes not in the hardcoded list (e.g. a browser refresh on /faktiska or /udens-temperatura) 404ed instead of loading the app — a known limitation that was actually hit in production. Real files now serve as-is; anything else falls back to index.html so the SolidJS router handles it, matching the existing "TODO rewrite in more generic way" comment. Future routes need no backend changes.
This commit is contained in:
@@ -2,6 +2,7 @@ package server
|
||||
|
||||
import cats.effect._
|
||||
import cats.implicits.toTraverseOps
|
||||
import cats.syntax.semigroupk._
|
||||
import com.comcast.ip4s.IpLiteralSyntax
|
||||
import data.DataService
|
||||
import db.PostgresService
|
||||
@@ -203,18 +204,20 @@ class Server(postgresService: PostgresService, dataService: DataService, fetch:
|
||||
|
||||
private val apiRoutesCors = CORS(apiRoutes, corsConfig)
|
||||
|
||||
private val httpApp = Router(
|
||||
"/" -> staticcontent.fileService[IO](FileService.Config("./web/dist")),
|
||||
"/api" -> apiRoutesCors,
|
||||
// Real files (JS/CSS/images/favicon) are served as-is; anything else falls
|
||||
// back to index.html so the SolidJS router can handle it client-side. This
|
||||
// replaces an explicit per-route list that silently 404ed on a direct hit
|
||||
// (e.g. a browser refresh) for any client-side route not on the list —
|
||||
// real, observed on /faktiska and /udens-temperatura in production.
|
||||
private val assets = staticcontent.fileService[IO](FileService.Config("./web/dist"))
|
||||
private val spaFallback = HttpRoutes.of[IO] {
|
||||
case req @ GET -> _ =>
|
||||
StaticFile.fromPath(Path("./web/dist/index.html"), Some(req)).getOrElseF(NotFound())
|
||||
}
|
||||
|
||||
// TODO rewrite in more generic way
|
||||
"/station" -> staticcontent.fileService[IO](FileService.Config("./web/dist")),
|
||||
"/cities" -> staticcontent.fileService[IO](FileService.Config("./web/dist")),
|
||||
"/latvia" -> staticcontent.fileService[IO](FileService.Config("./web/dist")),
|
||||
"/database" -> staticcontent.fileService[IO](FileService.Config("./web/dist")),
|
||||
"/harmonie" -> staticcontent.fileService[IO](FileService.Config("./web/dist")),
|
||||
"/lvgmc-forecast" -> staticcontent.fileService[IO](FileService.Config("./web/dist")),
|
||||
"/bridinajumi" -> staticcontent.fileService[IO](FileService.Config("./web/dist")),
|
||||
private val httpApp = Router(
|
||||
"/api" -> apiRoutesCors,
|
||||
"/" -> (assets <+> spaFallback),
|
||||
).orNotFound
|
||||
|
||||
def run: IO[ExitCode] =
|
||||
|
||||
Reference in New Issue
Block a user