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

Add ability to server render the frame #24

Open
ceopaludetto opened this issue Jul 16, 2023 · 4 comments
Open

Add ability to server render the frame #24

ceopaludetto opened this issue Jul 16, 2023 · 4 comments
Labels
documentation Improvements or additions to documentation

Comments

@ceopaludetto
Copy link

ceopaludetto commented Jul 16, 2023

I'm creating a docs website using whyframe and astro, the react integration works pretty well, but every reload on the page causes a little flash in the iframe, so after reading the source code i've imagined if we can expose a createServerApp from the virtual import:

---
// /frames/default.astro
import { createServerApp } from "whyframe:app"

const html = await createServerApp(Astro.url.searchParams.get("frame-id"))
---

<Fragment set:html={html} />

So instead of collecting the id from dataset attributes we can send directly in the frame URL, like so:

<iframe src="/frames/default?frame-id=some-id" />

And then, in the createServerApp internals we dynamic import the frame data and render with the matched framework function(e.g. renderToString). What do you think?

@bluwy
Copy link
Owner

bluwy commented Jul 17, 2023

Hi. Yeah currently createApp() only implements client-side rendering. createServerApp is an interesting idea, my initial concern would be how to generate both the SSR code and hydration code during build. Otherwise it would be uninteractable.

Regarding the flash, I'm not entirely sure if SSR would solve this too. IIRC browsers only fetch the iframe resources after the page is loaded, so a flash would always be visible unless it's already cached. CSR is usually fairly fast too and for iframes they can't be indexed by a crawler.

@bluwy
Copy link
Owner

bluwy commented Jul 17, 2023

I actually also have a script to make the flash not so obvious/jarring: https://github.com/bluwy/whyframe/blob/72e34498748f0b45d9272c886e123efd4dd24e17/docs/src/components/IframeNoFlash.astro

@ceopaludetto
Copy link
Author

ceopaludetto commented Jul 17, 2023

Hi again, I initially write this issue because I've imagined that SSR could speed up the show source process, but after investigation I realized that the source code is always available(not only in the client side). So instead of getting the source code using the util getWhyframeSource I was able to get by accessing the props(this could be included in the docs somehow?):

type AddCodeProps = {
  children: ReactElement;
};

function AddCode({ children }: AddCodeProps) {
  const code = children.props["data-why-source"]; // here is the magic

  return (
    <>
      {children}
      <Suspense>
        <Code className="rounded-t-none border-t-0" lang="tsx">
          {code}
        </Code>
      </Suspense>
    </>
  );
}

export type StoryProps = {
  children: ReactNode;
};

export function Story({ children }: StoryProps) {
  return (
    <AddCode>
      <iframe data-why className="w-full rounded-t-md border border-surface-container-high">
        {children}
      </iframe>
    </AddCode>
  );
}

This allow the syntax highlight to render on the server side even if the iframe is not loaded. For the flash I'll use the script which seems to be a better solution, thank you!

@bluwy
Copy link
Owner

bluwy commented Jul 18, 2023

Yup, you can definitely use children.props["data-why-source"] as a fast path for now. I didn't document this because it's meant to be internal. But given how long I haven't changed that I guess it's fair to document that.

I still have plans to change that up in the future, but it'll be part in a new set of breaking changes anyway (that I still haven't got to finish up).

@bluwy bluwy added the documentation Improvements or additions to documentation label Jul 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

2 participants