Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Broken links in Browser.application with prerendered content #105

Open
ChristophP opened this issue Mar 25, 2020 · 1 comment
Open

Broken links in Browser.application with prerendered content #105

ChristophP opened this issue Mar 25, 2020 · 1 comment

Comments

@ChristophP
Copy link

ChristophP commented Mar 25, 2020

Problem
For SEO reasons as well as to prevent FOUC we prerender our Elm apps with certain tools. That means that by the time the Elm app initializes the DOM is already filled and the Elm app is supposed to "take it from there".
However, links are broken then, in the sense that they will cause a full page reload instead of be intercepted by Browser.application.

Cause

Before Browser.application initializes it seems to call _VirtualDom_virtualize() here in order to hydrate the vdom. Since the content is the same it would render initally the DOM will be left as is. This is problematic because links will not get the same treatment as other links in Browser.application that is happening here

Proposed solution
Add special treatment for links when virtualizing the DOM in this scenario so that clicks on those links will be intercepted as well.

Possible workaround
Whiping the DOM clean before Elm initializes. :-/

SSCCE

<html>
<!-- note the lack of whitespace after the body tag, to make sure no text nodes get inserted by the virtual DOM virtualize function -->
<body><a href="/blog">Prerendered: This link WILL NOT be intercepted by Browser.application</a>
  <script src="/elm.js"></script>
  <script>
    Elm.Main.init()
  </script>
</body>
</html>
module Main exposing (..)

import Browser
import Html exposing (..)
import Html.Attributes exposing (href)

view model =
    Browser.Document "SSCCE"
        [ a [ href "/blog" ] [ text "Prerendered: This link WILL NOT be intercepted by Browser.application" ]
        , br [] []
        , br [] []
        , a [ href "/blog" ] [ text "Dynamically rendered: This link WILL be intercepted by Browser application" ]
        ]

main =
    Browser.application
        { init = \() url key -> ( (), Cmd.none )
        , view = view
        , update = \msg model -> ( model, Cmd.none )
        , subscriptions = \() -> Sub.none
        , onUrlRequest = \urlRequest -> ()
        , onUrlChange = \url -> ()
        }
{
    "type": "application",
    "source-directories": [
        "src"
    ],
    "elm-version": "0.19.1",
    "dependencies": {
        "direct": {
            "elm/browser": "1.0.2",
            "elm/core": "1.0.5",
            "elm/html": "1.0.0"
        },
        "indirect": {
            "elm/json": "1.1.3",
            "elm/time": "1.0.0",
            "elm/url": "1.0.0",
            "elm/virtual-dom": "1.0.2"
        }
    },
    "test-dependencies": {
        "direct": {},
        "indirect": {}
    }
}
@aggressivepixels
Copy link

Just got hit by this, and can confirm that wiping the DOM is a valid workaround, but a fix would definitely be nice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants