Closed eduardonunesp closed 5 years ago
@eduardonunesp I don't get what you are trying to ask. Angular uses #/path1/path2
as routing. That is not specified by the server or in this case, gin. You just need to serve a folder (or root path) as static, and let the angular magic do the rest.
@javierprovecho the idea is when you use Angular in HTML5 mode, the app don't use the #
just act like non-SPA. For instance when I was using NGINX it needed to config a sort of catch all URL.
To help clarify the idea, please take a look in this article http://www.codelord.net/2015/05/12/angularjs-how-to-setup-pushstate-with-html5mode/
The SPA server is a common pattern for tidy URLs. Angular, React, Aurelia, these all can use #
or they can use "pretty" urls without the #
, it's up to the server to return the index.html
no matter what url is requested.
In node.js I have handled this by catching a 404 and returning the index.html
I'm using a similar strategy using gin:
router.NoRoute(func(c *gin.Context) {
c.File("./public/index.html")
})
The actual implementation will run a regex on the Request.URL.Path and only return index.html when the regex is true. So if you ask for /unknown-image.png
you'll still get a 404.
I also plan to server SPA with gin,
@djensen47 ,base on your comments, I have the code
router.NoRoute(func(c *gin.Context) {
dir, file := path.Split(c.Request.RequestURI)
ext := filepath.Ext(file)
if file == "" || ext == "" {
c.File("./public/index.html")
} else {
// strings.Split(file, "?")
c.File("./public" + path.Join(dir, file))
}
})
but when after adding service workers... I will get lot of error here. I thought a better SPA support for gin depends on the issue of httprouter.
and there will be lots of scenario to handle like: https://www.dreambo8563.tech/manifest.28f941dd3f089e9cfec1.js?aa (path with query) https://github.com/julienschmidt/httprouter/issues/73
I ended up doing this in labstack/echo instead. Echo actually has the plugins required to make this work seemlessly. We also open sourced the project and call it SPArge: https://github.com/BrewdHQ/sparge
@djensen47 yes, echo can support scenario well
See the source code from go-ggz/ggz
https://github.com/go-ggz/ggz/blob/8e98db8d743a66bf2f3ea8dbb8c48686abc150a5/router/router.go#L79-L80
Any solution for this to serve spa with frontend routing?
You can handle all the routes by including a separate line for each one of them. The below example handles 3 routes, that are, '/' '/login' and '/signup'. I am using reactjs, but i think (not sure!) this will work for other libraries/frameworks (like angular) as well. (The 'build' folder is obtained by the command 'npm run build' in react.)
router := gin.Default()
router.Use(static.Serve("/", static.LocalFile("./build", true)))
router.Use(static.Serve("/login", static.LocalFile("./build", true)))
router.Use(static.Serve("/signup", static.LocalFile("./build", true)))
router.NoRoute(func(c *gin.Context) {
c.JSON(404, gin.H{
"code": "PAGE_NOT_FOUND", "message": "Page not found", // or use c.File("./public/index.html")
})
})
so what is the final solution?
so what is the final solution?
@amboowang a simple solution is
//configuration to SAP applications
router.Use(static.Serve("/", static.LocalFile("./assets/build", true)))
router.NoRoute(func(c *gin.Context) {
if !strings.HasPrefix(c.Request.RequestURI, "/api") {
c.File("./assets/build/index.html")
}
//default 404 page not found
})
What is the difference between using the contrib static module and the built in router.Static? Is the contrib module required to do a root "/" static route? I get an error when trying to do so with r.Static if I have any other routes.
Just to add to that solution which worked for me as well, in the served html file I had a reference to a js file of type
<script src="./myfile.js"></script>
that was causing me trouble while resolved with a path like /path/secondpath
and looking ok with just /path
and I had completely forgotten about this head option
<base href="/">
I have an Angular app to serve using
Static middleware
, and AngularJS is a SPA framework, means it needs to catch all kinds of routes. My question is: can I do something like: