Skip to content

Routers, PushState, and Server-side content #1801

Closed
@mikeknoop

Description

Here is my predicament:

We have a number of frontend-only and backend-only routes (that is, content is generated via frontend Backbone views or backend server-rendered content).

For those backend routes, we still want Backbone to initialize because we use it for various page activities and handle navigation between frontend pages. The only thing special about our backend routes is the server pre-renders some HTML content into the body (think legacy apps, SEO, etc). Backbone works great out-of-the-box for PushState-enabled browsers in the above environment.

The problem is non-PushState browsers. Backbone intelligently swaps out URL fragments when Backbone history is started in the presence of a non-PushState browser:
https://zapier.com/app/support -> https://zapier.com/app/#support

This causes a full-page refresh in non-PushState browsers. Because of the hash #, the server is not sent the fragment. The server only sees https://zapier.com/app/ and cannot know which backend content may need to be loaded on the second round trip.

We are working around this by using two routers, re-starting history between the router initialization, and faking some browser environment variables for Backbone:

# light routing starts here, light routing is for backend-only routes
# fake pushState existence so Backbone won't auto-redirect
if not window.history.pushState?
   window.history.pushState = (() -> return)
lightRouter = new LightRouter()
lightRouteFound = Backbone.history.start {pushState: false, root: '/'}

# normal backbone routing starts here
# restart history so it picks up on a second set of new non-light routes
Backbone.history.stop()
router = new Router()
routeFound = Backbone.history.start {pushState: true, root: '/'}

# load 404 page if no initial route matched the URL in the address bar
router.notfound() if not routeFound and not lightRouteFound

I am curious what other solutions exist and if Backbone should be handling this scenario.

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions