plotly / dash-labs

Work-in-progress technical previews of potential future Dash features.
MIT License
140 stars 39 forks source link

Multi-Page Apps [Feature request] Make Dash SEO-friendly #49

Open eliasdabbas opened 2 years ago

eliasdabbas commented 2 years ago

A React app that is SEO-friendly out of the box would be a big deal, especially with support for multi-page apps and URLs.

The main code that converts the layout of the app to HTML is already done, and is being used in the Dash docs website.

We basically parse the app’s layout and recursively convert it to HTML. Then we modify the app’s index_string with the Dash.interpolate_index function.

The only trick I can see is if developers make changes to the app’s index_string, and we need to make sure we don’t make changes that conflict with theirs.

If this sounds interesting, we can explore this further, and I'm happy to help whichever way I can.

Thanks!

chriddyp commented 2 years ago

This could be really great! Especially with the pages/ framework, we have a much better framework for know what to HTML render for various pages.

Before we make this generally available in dash, I think we should solve the solve the “flash” issue in dash-renderer.

Basically dash-renderer will wipe out the initial HTML content that we display on page load with a blank

before it renders the content in React. This leads to a flash of empty content between our "inferred HTML" and the real React components that are rendered. In an ideal world, it’d transition directly from “plain HTML” to rendered Dash HTML

The other thing to investigate would be if we can update the styling of the inferred HTML to signify that this is just a intermediate loading screen. Something like skeleton states but with real content.

eliasdabbas commented 2 years ago

Thanks @chriddyp

This could be really great! Especially with the pages/ framework, we have a much better framework for know what to HTML render for various pages.

Yes, I'm really liking the granularity of pages/ and how it dynamically changes titles, descriptions, and other metas.

My initial thinking is that we can can add a body parameter to the register_page function, and you can either keep it as is (which defaults to convert_to_html(app.layout) or you can override it if you want. This would be consistent with how other params behave.

def register_page(
    module,
    ...
    title=None,
    description=None,
    body=None,
    ...
    **kwargs,
):

The resulting string would be inserted right above this part, something like this:

     ...           
</head>
    <body>
       {body_html}
       {app_entry}
     <footer>
      {config}
      ...
.format(body_html=convert_to_html(layout)

Does this make sense? I'll try out a few things, and will let you know.

Let me know if I can help on the flash issue, and if what your thoughts are on what to tackle next.