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

Support for Server Component Skeletons #243

Open
jrstrunk opened this issue Feb 16, 2025 · 0 comments
Open

Support for Server Component Skeletons #243

jrstrunk opened this issue Feb 16, 2025 · 0 comments

Comments

@jrstrunk
Copy link

Hello! As previously discussed, it would be nice to be able to specify a skeleton for server components. I use the word skeleton and not "loading" because it is not really primarily for loading. Though it can also be used as a loading state for server components, it is also very useful in places where JS is not available (like when prefetching HTML, web scrapers (and SEO stuff), page fragment links, for users with JS disabled, etc.).

I know this may not directly correlate to v5 code, but in v4 adding support for this required just one line of code:

var LustreServerComponent = class extends HTMLElement {
  static get observedAttributes() {
    return ["route"];
  }
  constructor() {
    super();
    this.attachShadow({ mode: "open" });
    this.shadowRoot.innerHTML = '<slot name="skeleton"></slot>'; // <- this is the one new line!
    this.#observer = new MutationObserver((mutations) => {
    // ...
    });
  }
  // ...
}

Then, it can be used like:

pub fn render_with_skeleton(name: String, skeleton: element.Element(msg)) {
  element.element(
    "lustre-server-component",
    [server_component.route("/" <> name)],
    [html.div([attribute.attribute("slot", "skeleton")], [skeleton])],
  )
}

For user-discoverability and ease, I might suggest adding a skeleton function to the server_component module, which could be like so:

pub fn skeleton(element: element.Element(msg)) {
  html.div([attribute.attribute("slot", "skeleton")], [skeleton])
}

which could then easily be used like:

  element.element(
    "lustre-server-component",
    [server_component.route("/" <> name)],
    [server_component.skeleton(html.p([], [html.text("Spooky!")]))],
  )

If you think this is a good practice, the server_component.component function could also be changed to take a skeleton element list (could be passed as [] if not wanted) to encourage users to provide one.

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

1 participant