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

custom response and constructor props for SSR pages #1177

Open
thescientist13 opened this issue Nov 3, 2023 · 0 comments
Open

custom response and constructor props for SSR pages #1177

thescientist13 opened this issue Nov 3, 2023 · 0 comments
Labels
Adapter CLI feature New feature or request SSR
Milestone

Comments

@thescientist13
Copy link
Member

thescientist13 commented Nov 3, 2023

Summary

Coming out of #952 , where in we introduced Web Server Components, that took in an instance of Request as a constructor prop

export default class PostPage extends HTMLElement {
  constructor(request) {
    super();

    const params = new URLSearchParams(request.url.slice(request.url.indexOf('?')));
    this.postId = params.get('id');
  }

  async connectedCallback() {
    const { postId } = this;
    const post = await fetch(`https://jsonplaceholder.typicode.com/posts/${postId}`).then(resp => resp.json());
    const { id, title, body } = post;

    this.innerHTML = `
      <h1>Fetched Post ID: ${id}</h1>
      <h2>${title}</h2>
      <p>${body}</p>
    `;
  }
}

We would want to make sure we could compliment this with the ability to "customize" the response, in addition the already provided HTML. This would be useful for pages, especially in the case of response headers, for setting things like:

  • Cookies (e.g. Set-Cookie)
  • Cache Headers
  • Custom Headers

In addition, being able to customize constructor props would be nice, to encompass all that data fetching / massaging outside of the component definition, where things could awkward within the limitation of a synchronous constructor and could make unit testing easier through dependency injection.

Details

As seen in #880, I think a custom "loader" function could be used for a double-purpose here, in that the loader function can be a mechanic for hydration, in that the user can return some JSON serialiaziable data, and we can inline that into the HTML of the page as well as pass it in as a custom constructor prop.

export default class PostPage extends HTMLElement {
  constructor({ post }) {
    super();

    this.post = post;
  }

  async connectedCallback() {
    const { id, title, body } = this.post;

    this.innerHTML = `
      <h1>Fetched Post ID: ${id}</h1>
      <h2>${title}</h2>
      <p>${body}</p>
    `;
  }
}

export async function loader(request) {
  const params = new URLSearchParams(request.url.slice(request.url.indexOf('?')));
  const postId = params.get('id');
  const post = await fetch(`https://example.com/posts/${postId}`).then(resp => resp.json());

  return { post };
}

From there, perhaps we can also define an instance of Response to be returned, and then we can just extract / merge everything but the body, so that something like this could be possible?

export async function loader(request) {
  const params = new URLSearchParams(request.url.slice(request.url.indexOf('?')));
  const postId = params.get('id');
  const post = await fetch(`https://example.com/posts/${postId}`).then(resp => resp.json());

  return {
    props: { post },
    response: new Response('', {
      headers: new Headers({
        'Cache-Control': 'max-age=604800'
      })
    })
  };
}

I'm not quite sure how to reconcile this with #880 where all we care about is the custom prop, so not sure we can get this all from a Response, or maybe we can just pass in a mutable reference to the response being managed by Greenwood? 🤔

export async function loader(request, response) {
  const params = new URLSearchParams(request.url.slice(request.url.indexOf('?')));
  const postId = params.get('id');
  const post = await fetch(`https://example.com/posts/${postId}`).then(resp => resp.json());

  response.headers.set( 'Cache-Control', 'max-age=604800');

  return { post },
}

The pilot for this can be Lit's SSR hydration support added in #1201

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Adapter CLI feature New feature or request SSR
Projects
Status: 🔖 Ready
Development

No branches or pull requests

1 participant