-
-
Notifications
You must be signed in to change notification settings - Fork 98
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: add `initial` property in frame handler options * chore: format * feat: add `number` type to `refreshing` * nit: add jsdoc * nit: lowercase header key * nit: try to pass both values * feat: add `.image` handler, drop defining images in frame options * chore: changesets * nit: lint * nit: ban `imageOptions` in frame response if `image` is `string` * nit: trying to release canary * ci: add setup bun step * feat: detect image handler presence automatically * nit: lint * chore: changesets * docs: up * docs: up --------- Co-authored-by: dalechyn <dalechyn@users.noreply.github.com>
- Loading branch information
Showing
19 changed files
with
778 additions
and
120 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"frog": patch | ||
--- | ||
|
||
Introduced `.image` handler to handle images separately from the frame handler. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { Button, Frog } from 'frog' | ||
import { Heading, VStack, vars } from './ui.js' | ||
|
||
export const app = new Frog({ | ||
ui: { vars }, | ||
}) | ||
.frame('/', (c) => { | ||
return c.res({ | ||
image: '/refreshing-image/cool-parameter', | ||
intents: [<Button>Check again</Button>], | ||
}) | ||
}) | ||
.image('/refreshing-image/:param', (c) => { | ||
return c.res({ | ||
imageOptions: { | ||
headers: { | ||
'Cache-Control': 'max-age=0', | ||
}, | ||
}, | ||
image: ( | ||
<VStack grow gap="4"> | ||
<Heading color="text400"> | ||
Current time: {new Date().toISOString()} | ||
</Heading> | ||
</VStack> | ||
), | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# Image Handler [Moving image rendering into another handler.] | ||
|
||
Internally, **Frog** serves an image handler for every Frame at the frame path + `/image` endpoint. | ||
Although it comes with ease, this approach has several limitations: | ||
- Making *refreshing frames* would not be possible as initial frame response is cached indefinitely and image URL would change | ||
if the image changes. | ||
- If your Frame is heavily composed of different UI elements, browsers might *cut* a part of image URL that contains the compressed | ||
image in the query parameter, making it fail to render. | ||
|
||
In order to mitigate that, **Frog** has `.image` handler that can be used to serve an image at a *static URL*. | ||
|
||
```tsx twoslash | ||
// @noErrors | ||
import { Frog } from 'frog' | ||
|
||
export const app = new Frog() | ||
|
||
app.frame('/', (c) => { // [!code focus] | ||
return c.res({ | ||
image: '/img' | ||
/* ... */ | ||
}) | ||
}) | ||
|
||
app.image('/img', (c) => { // [!code focus] | ||
return c.res({/* ... */}) | ||
}) | ||
``` | ||
|
||
Since the image URL is static now, you're open to add `Cache-Control: max-age=0` header to image response to achieve refreshing initial frame. | ||
|
||
:::warning | ||
By default, image response will have `Cache-Control: public, immutable, no-transform, max-age=31536000` header set. | ||
However, since HTTP headers are case-insensitive, different frameworks (i.e. Next.JS, Vercel) might | ||
treat them differently and use lowercased format of such. | ||
|
||
Thus, if you're overriding the `Cache-Control` header and can't see the changes to kick in – try lowercasing the header. | ||
::: | ||
|
||
```tsx twoslash | ||
// @noErrors | ||
import { Frog } from 'frog' | ||
|
||
export const app = new Frog() | ||
|
||
app.frame('/', (c) => { | ||
return c.res({ | ||
image: '/img' | ||
/* ... */ | ||
}) | ||
}) | ||
|
||
app.image('/img', (c) => { | ||
return c.res({ | ||
headers: { // [!code focus] | ||
'Cache-Control': 'max-age=0' // [!code focus] | ||
}, // [!code focus] | ||
/* ... */ | ||
}) | ||
}) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.