Skip to content

Commit

Permalink
feat(assets): Allow users to set a custom endpoint to use for image o…
Browse files Browse the repository at this point in the history
…ptimization (#8467)

Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
  • Loading branch information
3 people authored Sep 13, 2023
1 parent c92e0ac commit ecc65ab
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/dirty-seahorses-move.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': minor
---

Add a new `image.endpoint` setting to allow using a custom endpoint in dev and SSR
22 changes: 22 additions & 0 deletions packages/astro/src/@types/astro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,28 @@ export interface AstroUserConfig {
* @name Image Options
*/
image?: {
/**
* @docs
* @name image.endpoint
* @type {string}
* @default `undefined`
* @version 3.1.0
* @description
* Set the endpoint to use for image optimization in dev and SSR. Set to `undefined` to use the default endpoint.
*
* The endpoint will always be injected at `/_image`.
*
* ```js
* {
* image: {
* // Example: Use a custom image endpoint
* endpoint: './src/image-endpoint.ts',
* },
* }
* ```
*/
endpoint?: string;

/**
* @docs
* @name image.service
Expand Down
4 changes: 3 additions & 1 deletion packages/astro/src/assets/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import type {
import { matchHostname, matchPattern } from './utils/remotePattern.js';

export function injectImageEndpoint(settings: AstroSettings) {
const endpointEntrypoint = settings.config.image.endpoint ?? 'astro/assets/image-endpoint';

// TODO: Add a setting to disable the image endpoint
settings.injectedRoutes.push({
pattern: '/_image',
entryPoint: 'astro/assets/image-endpoint',
entryPoint: endpointEntrypoint,
prerender: false,
});

Expand Down
1 change: 1 addition & 0 deletions packages/astro/src/core/config/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ export const AstroConfigSchema = z.object({
.default(ASTRO_CONFIG_DEFAULTS.redirects),
image: z
.object({
endpoint: z.string().optional(),
service: z
.object({
entrypoint: z
Expand Down
41 changes: 41 additions & 0 deletions packages/astro/test/core-image.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,47 @@ describe('astro:image', () => {
expect($('#local img').attr('data-service-config')).to.equal('bar');
});
});

describe('custom endpoint', async () => {
/** @type {import('./test-utils').DevServer} */
let customEndpointDevServer;

/** @type {import('./test-utils.js').Fixture} */
let customEndpointFixture;

before(async () => {
customEndpointFixture = await loadFixture({
root: './fixtures/core-image/',
image: {
endpoint: './src/custom-endpoint.ts',
service: testImageService({ foo: 'bar' }),
domains: ['avatars.githubusercontent.com'],
},
});

customEndpointDevServer = await customEndpointFixture.startDevServer({
server: { port: 4324 },
});
});

it('custom endpoint works', async () => {
const response = await customEndpointFixture.fetch('/');
const html = await response.text();

const $ = cheerio.load(html);
const src = $('#local img').attr('src');

let res = await customEndpointFixture.fetch(src);
expect(res.status).to.equal(200);
expect(await res.text()).to.equal(
"You fool! I'm not a image endpoint at all, I just return this!"
);
});

after(async () => {
await customEndpointDevServer.stop();
});
});
});

describe('proper errors', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const GET = async () => {
return new Response("You fool! I'm not a image endpoint at all, I just return this!", { status: 200 });
};

0 comments on commit ecc65ab

Please sign in to comment.