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

feat(context): introduce c.render() #1397

Merged
merged 2 commits into from
Sep 5, 2023
Merged

feat(context): introduce c.render() #1397

merged 2 commits into from
Sep 5, 2023

Conversation

yusukebe
Copy link
Member

@yusukebe yusukebe commented Sep 3, 2023

This PR introduces c.render() and c.setRenderer() functions. These functions enhance Hono's response handling, allowing for more flexible and modular response structures, especially useful for defining common parts of responses, like HTML layouts.

You can set a layout using c.setRenderer() within a custom middleware, as shown below:

app.use('*', async (c, next) => {
  c.setRenderer((content) => {
    return c.html(
      <html>
        <body>
          <p>{content}</p>
        </body>
      </html>
    )
  })
  await next()
})

Subsequently, you can utilize c.render() to create responses within this layout:

app.get('/', (c) => {
  return c.render('Hello!')
})

The output of which will be:

<html><body><p>Hello!</p></body></html>

Additionally, this feature offers the flexibility to customize arguments. To ensure type safety, types can be defined as:

declare module 'hono' {
  interface ContextRenderer {
    (content: string, head: { title: string }): Response
  }
}

Here's an example of how you can use this:

app.use('/pages/*', async (c, next) => {
  c.setRenderer((content, head) => {
    return c.html(
      <html>
        <head>
          <title>{head.title}</title>
        </head>
        <body>
          <header>{head.title}</header>
          <p>{content}</p>
        </body>
      </html>
    )
  })
  await next()
})

app.get('/pages/my-favorite', (c) => {
  return c.render(<p>Ramen and Sushi</p>, {
    title: 'My favorite',
  })
})

app.get('/pages/my-hobbies', (c) => {
  return c.render(<p>Watching baseball</p>, {
    title: 'My hobbies',
  })
})

Although this feature is set to debut as experimental, its transition to general availability will be swift, contingent upon no significant issues arising.

@ThatOneBro
Copy link
Contributor

Cool, I like this a lot! Seems like a good logical step for having different paths render in different ways. 👍

@yusukebe yusukebe changed the base branch from main to next September 5, 2023 07:00
@yusukebe
Copy link
Member Author

yusukebe commented Sep 5, 2023

Thanks! Merging now!

@yusukebe yusukebe merged commit 40c350c into next Sep 5, 2023
10 checks passed
@yusukebe yusukebe deleted the feat/context-render branch September 5, 2023 07:01
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

Successfully merging this pull request may close these issues.

None yet

2 participants