# Beacon path > Return HTTP 204 for first-party event requests with a CloudFront Function. `BeaconPath` adds the URL that receives browser events on your own domain. Add it to the CloudFront distribution that serves the measured site: ```typescript import { BeaconPath } from "@kensio/rainlytics/cdk"; new BeaconPath(this, "BeaconPath", { distribution, origin, }); ``` The default route is `/_rainlytics`. A CloudFront Function returns 204 during viewer request, before the cache or origin. CloudFront still records the request in its access log. `distribution` must be the CDK `Distribution` that serves the measured site. Pass any existing site origin. CloudFront requires an origin on every behavior, but a beacon request never reaches it. ## Request flow The browser sends an event in the query string: ```text GET /_rainlytics?v=1&e=route&p=%2Farticles%2F ``` CloudFront writes `cs-uri-query` independently of the cache key and origin forwarding settings. The function ignores the payload and returns the same empty response for every matching request. The event is stored in the same access logs as normal page requests. Rainlytics reads it through the same Glue table and Athena workgroup. ## Choose the path Reserve a path for the beacon: ```typescript new BeaconPath(this, "BeaconPath", { distribution, origin, path: "/_measure", }); ``` Pass the same value to `startBeacon` and to any beacon rollup request. Rainlytics rejects a path without a leading slash or a path containing a query string. Do not use a real page path. Each event would then look like a request for that page and could download its body if the edge function were missing. ## Protocol and cache behavior The path is HTTPS-only by default. Plain HTTP receives 403. A redirect would require a second request, which is unreliable when the browser sends the event while leaving a page. Change the policy only when the site requires it: ```typescript import { ViewerProtocolPolicy } from "aws-cdk-lib/aws-cloudfront"; new BeaconPath(this, "BeaconPath", { distribution, origin, viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS, }); ``` The managed cache policy excludes query strings from the cache key. The function normally returns before CloudFront checks the cache. If the function is removed, this policy uses one cache key for the path. The response includes `cache-control: no-store`, which prevents a browser from satisfying a repeated event from its own cache. ## Limits and cost CloudFront accepts up to 8,192 bytes for the path and query string and 32,768 bytes for the complete request. Events above either limit receive 414, and CloudFront drops their payload. A viewer-request CloudFront Function costs $0.10 per million invocations at the standard pay-as-you-go rate, before free-tier allowances. CloudFront request and log storage charges also apply. Check [CloudFront pricing](https://aws.amazon.com/cloudfront/pricing/) for your plan. The function handles event requests entirely at the edge and sends no traffic to the origin. ## Logged result type CloudFront records a successful event with status 204 and result type `FunctionGeneratedResponse`. The cache hit ratio counts `Hit`, `RefreshHit` and `Miss` only. `FunctionGeneratedResponse` therefore stays outside the ratio. --- This page: https://rainlytics.com/beacon-path/ Index of every page: https://rainlytics.com/llms.txt