Giter VIP home page Giter VIP logo

Comments (13)

dillonkearns avatar dillonkearns commented on May 23, 2024 2

Hello @michaelglass! I would like to support flags and ports eventually.

For that particular use case, I would actually recommend using Media Queries. A couple of benefits:

  1. It prevents page flashes for the pre-rendered page (because if you depend on the dimensions, then it will use the dimensions of the pre-rendering engine, and it will have to adjust once the live Elm app takes over in the users browser)
  2. You don't have to pass around state as much, so it's a nicer, more declarative experience (in my opinion). I like to use built-in web platform features when possible for that reason.

Here's an Ellie example illustrating that technique:

https://ellie-app.com/6Xw2jmCLHmYa1

from elm-pages.

dillonkearns avatar dillonkearns commented on May 23, 2024 1

Flags are wired up now as of the 2.0.0 NPM package/8.0.0 Elm package package!

See the Pages.Flags docs. As described there, flags not available during pre-render (because pre-render occurs before the user visits the page so the user's session doesn't yet exist). I think this issue is now resolved, hope it's useful!

from elm-pages.

dillonkearns avatar dillonkearns commented on May 23, 2024

Hey! Yes, that's been on my radar. It's not deterministic in the way that most of the Elm code is guaranteed to be, but that's not a problem actually (just something to use at your own risk of course!).

It's been on my radar, I think it makes sense to have the ability to pass in flags. Just to help me with the design, could you tell me a little about your particular use case?

from elm-pages.

rovdyl avatar rovdyl commented on May 23, 2024

That's about what I was suspecting, but I'm glad to hear it's on your radar! As long as it's made clear that this may cause unexpected behavior if used improperly, I doubt many people will have many issues with it.

My particular use case is pretty simple. I hope to use it so that my site can remember user credentials upon reloading the page. A combination of a simple json web token and some random bytes used for oauth state (generated upon initially visiting the site and stored for all future visits), both stored in the browser's local storage. This may expand in the future but for now that would be all I need.

It may be useful to have some sort of way to tell if my Elm code is being run during the pre-rendering phase or on an actual page visit. I like to distinguish between whether I don't know that I'm logged in yet (because I'm currently checking the credentials against the api to see if they're valid/get the users current info) and I'm actually logged out (no credentials have been stored yet). In the case of pre-rendering, I would actually like to render it as if I don't know yet, as opposed to as if I'm logged out since no credentials would be passed in to the flag during the pre-rendering phase, if that makes sense.

It's a somewhat minor distinction, and would hardly be a deal breaker if not added, but it's something I think I would appreciate nonetheless.

from elm-pages.

michaelglass avatar michaelglass commented on May 23, 2024

Elm-ui suggests passing in window dimensions as flags (https://package.elm-lang.org/packages/mdgriffith/elm-ui/latest/Element#Device) when implementing reactivity. I'd love this functionality as well.

from elm-pages.

synalysis avatar synalysis commented on May 23, 2024

I'd like to pass as a flag the operating system of the user in order to link the download button to a Windows or Linux version.

from elm-pages.

synalysis avatar synalysis commented on May 23, 2024

And I'd like to pass the current browser language so I can load a JSON file with UI translations accordingly.

from elm-pages.

dillonkearns avatar dillonkearns commented on May 23, 2024

Hello! Thanks for sharing the use case @synalysis.

The tricky thing here is that if elm-pages had flags and you load that JSON file with translations, it's actually misleading because of the pre-rendering lifecycle. It's going to pre-render with flags from the Puppeteer renderer. The language (and other things in the JS environment) will be different once the app loads in the users browser and starts to hydrate. So with your use case, it would pre-render with one language, and then have a flash when it changes languages if the user's language wasn't the same as Puppeteer on your system.

You can get the same behavior as a flag by sending it through with an initial port right now. But it's a little more accurate in modeling the actual state because you have to explicitly handle the state before that data is present.

I'm a little worried about having unintuitive flags behavior for users. At least doing them exactly as with a regular Elm app could lead to confusion and unintuitive behavior. Also, we want the initial pre-rendered state to match the initial state of the Elm app so that it transitions smoothly when the hydrated Elm app takes over the page.

I'm not sure if there's a design that could help with this. My gut feeling right now is that ports fit the conceptual picture of what's happening more accurately. But I'm still in the brainstorming phase here and would love to hear ideas on designs that could help with this.

from elm-pages.

synalysis avatar synalysis commented on May 23, 2024

In fact I have English strings in the UI and want to load (HTTP GET) - depending on the browser language/locale a JSON file with the "English" -> "Translated" mappings only if necessary.

Additionally dates and times should be formatted depending on the browser locale.

So it's totally ok to have the page (also pre-rendered) in English.

Is there any hint available how to add ports? It seems as if I have to touch the JS files in the NPM modules.

from elm-pages.

dillonkearns avatar dillonkearns commented on May 23, 2024

Yeah, for the ports you do:

const { Elm } = require("./src/Main.elm")
const initializePages = require("elm-pages")

initializePages({
  mainElmModule: Elm.Main
}).then(app => {
  // app.ports.somePort.subscribe(...)
})

Here's the PR that added it for reference: #50

We definitely need some documentation for this, and an example in the starter repo 👍

Regarding the flags, if I'm understanding correctly you're saying that you want to use flags both to pre-render, and to do the initial hydration render. I'm not sure what the implications for that are for pre-rendering, I need to think about that a little more. Of course the ideal is to have the pre-rendered content be exactly the same. I'm not sure if there are any blemishes to the hydration if the pre-rendered view differs from the initial hydrated view.

Could you report back how it goes with using ports, and how the hydration step looks? I'm wondering if we need to go out of our way to prevent people from getting in that state (if there are any negative consequences in the hydration being glitchy in any ways), or if we just need to try to make it intuitive to users what to expect when they use flags through the design.

from elm-pages.

dillonkearns avatar dillonkearns commented on May 23, 2024

Some potential ways that we could make it more clear to the user what to expect, for example, would be to have the type of flags be a custom type like:

type Flags value =
  FromPrerenderer value | FromUsersBrowser value

Something like that could be sufficient, potentially. I'm not quite sure, would love to hear people's thoughts on this.

from elm-pages.

synalysis avatar synalysis commented on May 23, 2024

Ports work for me sufficiently - apart from the locale I also pass if the browser/OS is running in dark mode. However, as with the screen sizes dark mode is better suited for media queries in CSS so the pre-rendered page looks the same as the hydrated one.

from elm-pages.

dillonkearns avatar dillonkearns commented on May 23, 2024

Sounds good, thanks for the update @synalysis. Yeah, media queries for dark mode is definitely ideal 👍

from elm-pages.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.