# Obfuscate an Astro site

@afterpack/astro is a thin integration that wires @afterpack/vite into Astro's own Vite pipeline.

Source: https://www.afterpack.dev/docs/frameworks/astro

Astro compiles every island and client bundle through its own Vite pipeline, and AfterPack integrates at the **bundler** level. `@afterpack/astro` exists so you don't have to hand-wire `vite: { plugins: [...] }` yourself.

Everything happens in [`@afterpack/vite`](https://www.afterpack.dev/docs/frameworks/vite)'s `generateBundle`, inside Astro's own Vite pipeline.

## Install

```bash
npm install -D @afterpack/astro
```

```js
// astro.config.mjs
import { defineConfig } from "astro/config";
import afterpack from "@afterpack/astro";

export default defineConfig({
  integrations: [afterpack()],
});
```

The default export and the named `afterpackAstro` export are the same function.

## Build

`astro build` now emits obfuscated output. `astro dev` is untouched, because the plugin only runs on the build's `generateBundle`, the hook [`@afterpack/vite`](https://www.afterpack.dev/docs/frameworks/vite) always uses. Astro writes the obfuscated chunks; the originals never reach `dist/`.

The obfuscated surface is the JavaScript Astro emits: island bundles and client scripts, typically under `dist/_astro/`. Server-rendered `.astro` template logic that never becomes client JS is out of scope.

## Verify

An `astro build` runs with the [production build mode](https://www.afterpack.dev/docs/config#build-mode), so ask for the [Protection Map](https://www.afterpack.dev/docs/protection-map) explicitly when you want to inspect one:

```js
integrations: [afterpack({ protectionMap: { enabled: true } })],
```

It writes to the gitignored `.afterpack/protectionMap.html`. The source-map side effect and the handling rules are [`@afterpack/vite`](https://www.afterpack.dev/docs/frameworks/vite#verify)'s.

*(live Protection Map demo embed — see https://www.afterpack.dev/protection-map-demo.html)*

## Options

Every [configuration key](https://www.afterpack.dev/docs/config) can be passed here as the options object, forwarded verbatim to [`@afterpack/vite`](https://www.afterpack.dev/docs/frameworks/vite#options), for example `afterpack({ preset: "hard", complexity: 40 })`. The type alias `AfterpackAstroOptions` is `AfterpackViteOptions`:

```js
integrations: [afterpack({ seed: "git", preset: "medium" })],
```

## Directives

Directives are read from your source by the plugin, before minification. [Block comments only](https://www.afterpack.dev/docs/directives#writing-one):

Directives inside `.astro` component files themselves are not captured. Put the directive in the island's `.jsx`/`.tsx` file:

```jsx
/* @afterpack preset=hard */
export function LicenseGate({ token }) {
  // ...
}
/* @afterpack end */
```

## Next

- [Frameworks](https://www.afterpack.dev/docs/frameworks): the full matrix.
- [Vite](https://www.afterpack.dev/docs/frameworks/vite): the plugin doing the actual work.
- [Protection Map](https://www.afterpack.dev/docs/protection-map): reading the report.
- [Directives](https://www.afterpack.dev/docs/directives): the marker grammar in full.
- [Builds & CI](https://www.afterpack.dev/docs/builds): seeds, dev-vs-prod, promoting the same bytes.
