---
title: "Observability"
description: "Monitor microfrontends routing with debug headers, Vercel Observability, and session tracing."
canonical_url: "https://vercel.com/academy/microfrontends-on-vercel/observability"
md_url: "https://vercel.com/academy/microfrontends-on-vercel/observability.md"
docset_id: "vercel-academy"
doc_version: "1.0"
last_updated: "2026-11-04T22:26:55.333Z"
content_type: "lesson"
course: "microfrontends-on-vercel"
course_title: "Microfrontends on Vercel"
prerequisites:  []
---

<agent-instructions>
Vercel Academy — structured learning, not reference docs.
Lessons are sequenced.
Adapt commands to the human's actual environment (OS, package manager, shell, editor) — detect from project context or ask, don't assume.
The lesson shows one path; if the human's project diverges, adapt concepts to their setup.
Preserve the learning goal over literal steps.
Quizzes are pedagogical — engage, don't spoil.
Quiz answers are included for your reference.
</agent-instructions>

# Observability

# Observability

When something routes wrong, you need to know why. Debug headers, observability dashboards, and session traces show exactly what happened to each request.

## Outcome

Enable and use debug headers to inspect routing decisions, and view microfrontends data in Vercel Observability.

## Debug Headers

When debug mode is enabled, responses include headers showing routing decisions:

| Header                                   | Description                                                |
| ---------------------------------------- | ---------------------------------------------------------- |
| `x-vercel-mfe-app`                       | Which app handled the request                              |
| `x-vercel-mfe-matched-path`              | Which routing pattern matched                              |
| `x-vercel-mfe-target-deployment-id`      | Deployment that served the request                         |
| `x-vercel-mfe-default-app-deployment-id` | Default app's deployment ID                                |
| `x-vercel-mfe-zone-from-middleware`      | App chosen by the default app's `proxy.ts` (flagged paths) |
| `x-vercel-mfe-response-reason`           | Internal routing reason                                    |

## Fast Track

1. Enable debug mode via cookie or Vercel Toolbar
2. Inspect response headers in DevTools
3. View routing data in Observability dashboard

## Hands-on Exercise 3.3

Enable debug mode and trace a request through the microfrontends layer.

### Part 1: Enable Debug Mode

**Option A: Set a cookie**

In your browser's DevTools console:

```javascript
document.cookie = "VERCEL_MFE_DEBUG=1; path=/";
```

Refresh the page. Now all responses include debug headers.

**Option B: Use Vercel Toolbar**

If you have the Vercel Toolbar installed:

1. Click the Vercel icon in the toolbar
2. Open the "Microfrontends" panel
3. Toggle "Enable Debug Mode"

### Part 2: Inspect Response Headers

1. Open DevTools → Network tab
2. Visit your deployed marketing domain at `/docs` (for example, `acme-marketing.vercel.app/docs`)
3. Click on the document request
4. Look at Response Headers:

```
x-vercel-mfe-app: acme-docs
x-vercel-mfe-matched-path: /docs/:path*
x-vercel-mfe-target-deployment-id: dpl_abc123xyz
x-vercel-mfe-default-app-deployment-id: dpl_def456uvw
```

This tells you:

- The `acme-docs` project handled this request
- It matched the `/docs/:path*` pattern
- The specific deployment IDs involved

### Part 3: View Observability Dashboard

1. Go to your Vercel dashboard (team or project scope both work)
2. Open **Observability**
3. Find **Microfrontends** in the **CDN** section

This view holds the microfrontends routing information Vercel stores for your traffic. Start here when a whole path seems off, then drop down to debug headers or a trace for a single request. The [observability docs](https://vercel.com/docs/microfrontends/troubleshooting#observability) cover where it lives.

### Part 4: Capture a Session Trace

Session tracing shows the full lifecycle of a request:

1. In the Vercel Toolbar on your deployment, open **Tracing** and select **Start Tracing Session**
2. Make a request to your microfrontends URL
3. From the toolbar's **Tracing** menu, select **View Session Traces**. The dashboard opens the logs filtered to your session.
4. Open the trace for your request
5. Expand the **Microfrontends** span

The span includes attributes:

| Attribute                              | Description                                        |
| -------------------------------------- | -------------------------------------------------- |
| `vercel.mfe.app`                       | Project that handled the request                   |
| `vercel.mfe.target_deployment_id`      | Deployment ID                                      |
| `vercel.mfe.default_app_deployment_id` | Default app deployment                             |
| `vercel.mfe.matched_path`              | Matched routing pattern                            |
| `vercel.mfe.app_from_middleware`       | The default app's `proxy.ts` decision (if flagged) |

## Debugging Common Issues

### "Wrong app is serving this path"

Check the headers:

```
Request: /docs/api
Expected: docs app
Actual header: x-vercel-mfe-app: acme-marketing
```

**Diagnosis:** The path pattern isn't matching. Check `microfrontends.json`:

```json
"acme-docs": {
  "routing": [
    { "paths": ["/docs", "/docs/:path*"] }
  ]
}
```

### "Redirect isn't working"

Remember the execution order:

```
Microfrontends → Headers → Redirects → proxy.ts → Rewrites
```

If your redirect is in the marketing app but the path routes to docs, the redirect never runs.

**Check:** Which app does the path route to?

```
x-vercel-mfe-app: acme-docs  // Redirect needs to be in docs app!
```

### "My proxy isn't running"

In a microfrontends group, the [docs](https://vercel.com/docs/microfrontends/troubleshooting#validatemiddlewareconfig) describe proxy (middleware) as running only in the default application. Check the header first:

```
Request: /app
x-vercel-mfe-app: acme-dashboard
```

That request went straight to the dashboard, so `apps/marketing/proxy.ts` never saw it. If your proxy isn't running, check:

1. Is the code in the default app's `proxy.ts` (`apps/marketing/proxy.ts`)?
2. Does the path stay with the default app, or is it a flagged path?
3. Does the `config.matcher` include this path?

Logic that has to run for `/app` belongs in the dashboard's own server code, like its `layout.tsx` or route handlers.

## Checking Headers From the Terminal

You might be tempted to build an `/api/debug` route that reads these headers inside the app. It comes back full of `null`. The `x-vercel-mfe-*` headers are **response** headers that Vercel adds on the way out, so your code never sees them on the request.

Read them where they arrive instead. DevTools works, and so does `curl -I`, which only fetches headers. Send the debug cookie along with the request:

```bash
curl -sI https://acme-marketing.vercel.app/docs \
  -H "Cookie: VERCEL_MFE_DEBUG=1" | grep -i "^x-vercel-mfe"
```

```
x-vercel-mfe-app: acme-docs
x-vercel-mfe-matched-path: /docs/:path*
x-vercel-mfe-target-deployment-id: dpl_abc123xyz
x-vercel-mfe-default-app-deployment-id: dpl_def456uvw
```

Swap in your own domain. If the command prints nothing, check for Deployment Protection first: a protected preview URL answers `curl` with a login page, which has no microfrontends headers. Use the production domain or the browser.

You'll run this check a lot, so save it as a script. Create `scripts/mfe-headers.sh` at the monorepo root:

```bash title="scripts/mfe-headers.sh"
#!/usr/bin/env bash
# Usage: ./scripts/mfe-headers.sh https://acme-marketing.vercel.app/docs
curl -sI "$1" -H "Cookie: VERCEL_MFE_DEBUG=1" | grep -i "^x-vercel-mfe"
```

Make it executable and point it at a few paths:

```bash
chmod +x scripts/mfe-headers.sh
./scripts/mfe-headers.sh https://acme-marketing.vercel.app/app
```

```
x-vercel-mfe-app: acme-dashboard
x-vercel-mfe-matched-path: /app
x-vercel-mfe-target-deployment-id: dpl_ghi789rst
x-vercel-mfe-default-app-deployment-id: dpl_def456uvw
```

The default app deployment ID matches the `/docs` request, because both requests read the same `microfrontends.json`.

## Commit

```bash
git add -A
git commit -m "feat(scripts): add a microfrontends debug header check"
```

## Done-When

- [ ] Debug mode enabled (cookie or toolbar)
- [ ] Can see the `x-vercel-mfe-app` header in DevTools
- [ ] `./scripts/mfe-headers.sh` prints `x-vercel-mfe-app: acme-docs` for `/docs` and `acme-dashboard` for `/app`
- [ ] Viewed microfrontends data in Observability dashboard
- [ ] Understand how to trace routing decisions

## Observability Checklist

When debugging microfrontends issues:

1. **Enable debug headers** - See which app handled the request
2. **Check matched path** - Verify the pattern is correct
3. **Compare deployment IDs** - Ensure the right deployment is serving
4. **View session trace** - See the full request lifecycle
5. **Check `proxy.ts`** - Confirm the default app's proxy ran (or didn't, and why)

## What's Next

Configure deployment protection and firewall rules that work across microfrontends.


---

[Full course index](/academy/llms.txt) · [Sitemap](/academy/sitemap.md)
