EdgeStore

Astro

Add EdgeStore uploads to Astro.

The Astro adapter handles server requests. The upload UI below uses a hydrated React component.

Setup

Install

npm install @edgestore/server@rc @edgestore/react@rc

Environment variables

Copy your project's keys from the dashboard to the backend env file:

.env
EDGESTORE_ACCESS_KEY=your-access-key
EDGESTORE_SECRET_KEY=your-secret-key

Add .env to .gitignore.

Backend

Configure an Astro server adapter for your deployment and enable the React integration for the UI below. The EdgeStore endpoint must run on demand; a static-only deployment cannot serve it.

Create src/pages/api/edgestore/[...edgestore].ts:

import { initEdgeStore } from '@edgestore/server';
import { createEdgeStoreAstroHandler } from '@edgestore/server/adapters/astro';

export const prerender = false;

const es = initEdgeStore.create();

const router = es.router({
  publicFiles: es.fileBucket(),
});

const handler = createEdgeStoreAstroHandler({
  router,
});

export { handler as GET, handler as POST };

export type EdgeStoreRouter = typeof router;

This bucket's files are accessible to anyone with the link.

Frontend

Create the React provider:

src/lib/edgestore.ts
import { createEdgeStoreProvider } from '@edgestore/react';
import type { EdgeStoreRouter } from '../pages/api/edgestore/[...edgestore].ts';

const { EdgeStoreProvider, useEdgeStore } =
  createEdgeStoreProvider<EdgeStoreRouter>();

export { EdgeStoreProvider, useEdgeStore };

Create the upload component:

src/components/FileUploader.tsx
import { useState } from 'react';
import { EdgeStoreProvider, useEdgeStore } from '../lib/edgestore';

export function FileUploader() {
  return (
    <EdgeStoreProvider>
      <FileUploaderInner />
    </EdgeStoreProvider>
  );
}

function FileUploaderInner() {
  const [file, setFile] = useState<File | null>(null);
  const { edgestore } = useEdgeStore();

  return (
    <div>
      <input
        type="file"
        onChange={(e) => {
          setFile(e.target.files?.[0] ?? null);
        }}
      />
      <button
        onClick={async () => {
          if (file) {
            const res = await edgestore.publicFiles.upload({
              file,
              onProgressChange: (progress) => {
                // you can use this to show a progress bar
                console.log(progress);
              },
            });
            // you can run some server action or api here
            // to add the necessary data to your database
            console.log(res);
          }
        }}
      >
        Upload
      </button>
    </div>
  );
}

Hydrate the component with client:load:

src/pages/index.astro
---
import { FileUploader } from '../components/FileUploader';
---

<html lang="en">
  {/* ... */}
  <body>
    <h1>EdgeStore with Astro</h1>
    <FileUploader client:load />
  </body>
</html>

On this page