소스 정보
- 저장소
- JSONbored/metagraphed
- 최근 소스 활동
- 2026년 7월 25일 06:58
- 감지된 SKILL.md 언어
- 영어
- 스타
- 12
- 포크
- 93
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/JSONbored/metagraphed --skill error-tracking-upload-source-maps-vite명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | error-tracking-upload-source-maps-vite |
| description | Upload source maps to PostHog Error Tracking for Vite |
| metadata | {"author":"PostHog","version":"1.36.0"} |
This skill helps you upload source maps (or platform debug symbols) so PostHog Error Tracking can resolve minified stack traces back to your original source.
references/vite.md - Upload source maps for vite - docsreferences/upload-source-maps.md - Upload source maps - docsreferences/cli.md - Upload source maps with cli - docsreferences/COMMANDMENTS.md - Framework-specific rules the integration must followThe overview lists every supported framework and build tool. The CLI reference covers posthog-cli sourcemap process, which injects chunk IDs and uploads maps in one step.
The stages of wiring up source map upload, in order. Each step has a short overview, gotchas under Tips, and per-technology notes under Examples. The reference files above are the source of truth for the exact, per-framework API — when this page and a reference disagree, follow the reference for Vite.
Source map upload authenticates with a personal API key, not the public project API key the SDK uses at runtime. The key needs error-tracking write access; the quickest path is the "Source map upload" preset on PostHog's personal API keys settings page.
init) will not work for uploads — it has no write scope for symbol sets.Wire source map generation, chunk-ID injection, and upload into your production build so every deploy ships matching maps. Depending on the platform this is either a build/bundler plugin, or a posthog-cli sourcemap process step run after the build (it injects chunk IDs and uploads in one pass). Follow the Vite reference for the exact wiring.
posthog-cli directly (no framework or bundler plugin), generating the maps is your responsibility — the CLI only injects chunk IDs into, and uploads, maps your build already produced. Two things must be true before posthog-cli sourcemap process works:
.js.map files).sourcesContent (the original source embedded inside the map). Without it PostHog has the line/column mappings but not the code, so traces can't be fully resolved.//# chunkId=… comment can't be matched to uploaded maps..map files from the deployed artifact, or use hidden source maps. Uploaded maps live in PostHog, not on your origin.tsconfig.json: "sourceMap": true and "inlineSources": true. Then run posthog-cli sourcemap process against the build output dir as a post-build step — it injects chunk IDs and uploads in one pass, and needs the upload credentials (see "Make credentials available at build time").DEBUG_INFORMATION_FORMAT = dwarf-with-dsym for Release.ENABLE_USER_SCRIPT_SANDBOXING = NO.$(DWARF_DSYM_FOLDER_PATH)/$(DWARF_DSYM_FILE_NAME)/Contents/Resources/DWARF/$(EXECUTABLE_NAME) in its Input Files, calling the SDK's bundled script — do not hand-roll the upload:
POSTHOG_INCLUDE_SOURCE=1 POSTHOG_CLI_DOTENV_FILE="${SRCROOT}/.env" "${BUILD_DIR%/Build/*}/SourcePackages/checkouts/posthog-ios/build-tools/upload-symbols.sh"POSTHOG_INCLUDE_SOURCE=1 POSTHOG_CLI_DOTENV_FILE="${SRCROOT}/.env" "${PODS_ROOT}/PostHog/build-tools/upload-symbols.sh"
Copy the invocation verbatim — the POSTHOG_INCLUDE_SOURCE=1 and POSTHOG_CLI_DOTENV_FILE prefixes HAVE to be there. This needs a recent posthog-cli (older ones silently ignore POSTHOG_CLI_DOTENV_FILE); the PostHog wizard installs it for you, so do not run npm install -g yourself.com.posthog.android Gradle plugin on the app module's build.gradle(.kts) (never the root project), per the reference — the plugin hooks the build and uploads automatically, do not hand-roll a posthog-cli step. Gotchas:
isMinifyEnabled = false, set it to true (keep the existing proguardFiles line) or nothing is uploaded.posthog-cli on the (v0.7.4+); the PostHog wizard installs it for you, so do not run yourself.The upload credentials must be readable by the build pipeline at build time, not merely present in a .env file. Whether .env is auto-loaded depends on the technology.
.env: Next.js, Nuxt and similar frameworks read .env into the build for you — nothing extra to do..env into import.meta.env for client code (only VITE_-prefixed vars), but does not put vars in process.env for your config to read. The upload credentials (POSTHOG_*, not VITE_-prefixed) are read when the plugin is constructed, so load them yourself — see the Vite example below..env: Rollup, plain webpack, and plain Node scripts. Load it explicitly — add dotenv (require('dotenv').config(), or import 'dotenv/config' for ESM) at the top of the bundler/config file.posthog-cli sourcemap process runs as its own package.json step (after the bundler), the CLI call is a separate child process and will not see env vars a loader set inside the bundler config. Point the CLI at the file directly: posthog-cli --dotenv-file <relative-path> sourcemap process … (the flag goes before the subcommand).process authenticates from the start. posthog-cli sourcemap process resolves credentials before it injects chunk IDs — the inject phase needs them too, not just the upload — and fails without them. Always pass --dotenv-file to the process invocation. (It can still appear to work if the developer once ran posthog-cli login, which leaves credentials in ~/.posthog — that won't exist in CI or on a teammate's machine.)POSTHOG_CLI_DOTENV_FILE="${SRCROOT}/.env" prefix points posthog-cli at the gitignored .env. POSTHOG_CLI_HOST is the API host (https://us.posthog.com), never the *.i.posthog.com ingestion host..env — bridge it in the app module's build script (see the Android example). Unset properties fall back to real POSTHOG_CLI_* environment variables, so the same wiring works in CI. The host var follows the same API-host rule as iOS above..env at build time; put the vars there and you're done.vite.config as a function and merge loadEnv into process.env so the config (and the PostHog plugin) can read the upload credentials. Pass '' as the third arg so non-VITE_ vars like POSTHOG_API_KEY are included — the default 'VITE_' prefix skips them:
import { defineConfig, loadEnv } from "vite";
export default ({ mode }) => {
process.env = { ...process.env, ...loadEnv(mode, process.cwd(), "") };
// process.env.POSTHOG_API_KEY is now readable by the plugins below
return defineConfig({
plugins: [/* … posthog source map plugin … */],
});
};
import 'dotenv/config' (or require('dotenv').config()) at the top of the config/entry file so the loader runs before the build reads the vars.--dotenv-file .env to the process invocation so it can authenticate:
"build": "tsc && posthog-cli --dotenv-file .env sourcemap process --directory ./dist --release-name my-app"
.env next to the .xcodeproj — the Run Script invocation's POSTHOG_CLI_DOTENV_FILE="${SRCROOT}/.env" prefix hands it to posthog-cli. No Xcode project wiring beyond the Run Script phase. In CI, set the POSTHOG_CLI_* values as job secrets instead — no .env on the runner..env at the Gradle project root, bridged into the upload tasks in the app module's build.gradle.kts:
import com.posthog.android.PostHogCliExecTask
import java.util.Properties
val postHogEnv = Properties().apply {
val envFile = rootProject.file(".env")
if (envFile.exists()) envFile.inputStream().use { load(it) }
}
tasks.withType<PostHogCliExecTask>().configureEach {
postHogEnv.getProperty("POSTHOG_CLI_API_KEY")?.let { postHogApiKey.set(it) }
postHogEnv.getProperty("POSTHOG_CLI_PROJECT_ID")?.let { postHogProjectId.set(it) }
postHogEnv.getProperty("POSTHOG_CLI_HOST")?.let { postHogHost.set(it) }
}
(Groovy build.gradle: same shape with .) In CI, set the values as job secrets instead — no on the runner.Write the personal API key and project identifiers into the env file your build reads. Reuse the file the project already uses — don't introduce a second one.
POSTHOG_* / NEXT_PUBLIC_POSTHOG_*), use that one. Otherwise, if exactly one env file exists use it; if several exist prefer .env. Only create a new file when none exists.posthog-cli direct upload → POSTHOG_CLI_API_KEY, POSTHOG_CLI_PROJECT_ID, POSTHOG_CLI_HOSTPOSTHOG_API_KEY, POSTHOG_PROJECT_ID, POSTHOG_HOST*_HOST var when you're not on US Cloud's default (e.g. EU Cloud or self-hosted); setting it explicitly always is safe. Follow the reference for the variant.Resolve two concrete commands for this project: the production build command (the one that uploads source maps) and the run command that launches the built app (so a test error can be triggered against the real artifact).
npm run build (next build). Run: npm run start (next start).npm run build. Run: npm run preview.npm run build. Run: node <built entry> — read package.json main/bin and the build output dir to name the real file (e.g. node dist/index.js)../gradlew assembleRelease. Run: launch on a device/emulator (Android Studio, or ./gradlew installRelease).xcodebuild is CI-only.flutter build apk / flutter build ios. Run: flutter run.npx react-native run-ios / npx react-native run-android.Source maps are only uploaded when the production build runs, so the environment that builds and deploys your app needs the same upload credentials you put in the env file. The whole job is: find where the production build command actually runs, then make the upload credentials reachable at that exact spot. Only ever edit CI/deploy files that already exist — never create a new workflow, pipeline, or deploy file. Wiring credentials means modifying the build/deploy config this project already has; it is never license to author new CI. The build is where maps inject + upload, and env does not automatically cross three boundaries — into a Docker build, into a nested/composite action, or into an SSH session. So trace the deploy path before editing anything:
Dockerfile? If the build command runs inside it (RUN <build>), the build happens in that image's build stage..github/workflows/? Open it and find the step that triggers the build, then follow it to where the build truly executes — it may be:
run: npm run build) on the runner,docker build / docker/build-push-action step (build runs in the image),uses: ./.github/actions/... local composite action — open that action.yml; the real build step is one layer down,ssh/deploy step (e.g. appleboy/ssh-action) whose script: runs the build on a remote server..gitlab-ci.yml, .circleci/config.yml, Jenkinsfile, bitbucket-pipelines.yml, azure-pipelines.yml, …)? Open it and find the job/stage that runs the production build. The principle is identical; apply it with your working knowledge of that provider — the examples below show the pattern to mirror.Dockerfile, no CI config, no build step you can trace? Don't guess — tell the user where the creds need to be (see "Untraceable setup" under Examples).deploy-backend.yml, or a Dockerfile/pipeline for another app) does not mean you should create a matching deploy-frontend.yml (or any new CI file) for the project you're instrumenting. Wire credentials only into the existing file that builds this project. If this project has no build/deploy config you can open and edit, it is untraceable: make no CI changes and hand the requirement to the user (see "Untraceable setup") — do not invent one.POSTHOG_CLI_* for direct posthog-cli; POSTHOG_* for bundler-plugin uploaders.).env on the runner (e.g. printf … > .env before the build), and never copy or un-ignore one into a Docker image: it's redundant, and a secrets file on disk can leak into artifacts, caches, or image layers. A build script that passes --dotenv-file .env to posthog-cli works unchanged in CI even though .env doesn't exist there: real environment variables take precedence over the file, and a missing file is skipped with a warning.ARG/ENV or BuildKit secret ids, ${{ secrets.* }} in GitHub Actions. The personal API key stays out of version control.docker build against a Dockerfile. Wire every layer the credentials must pass through, from the outer ${{ secrets.* }} reference down to the ARG/ENV in the build stage.ARG/ENV in the build stage (where the build command runs), never the runtime stage. That's both correct (the build needs them) and safer (the creds don't get baked into the shipped image).ARG/ would bake the API key into the shipped image ( reveals ; can reveal build args). Mount the key as a on the build instead — it exists for that command only and is never written to a layer (see the single-stage example). Plain / stays fine for the non-secret project ID and host.Dockerfile, no CI) Declare the credentials as build args and promote them to env vars before the build RUN, in the build stage:
FROM node:22-slim AS build
WORKDIR /app
# ...
ARG POSTHOG_CLI_API_KEY
ARG POSTHOG_CLI_PROJECT_ID
ARG POSTHOG_CLI_HOST
ENV POSTHOG_CLI_API_KEY=$POSTHOG_CLI_API_KEY \
POSTHOG_CLI_PROJECT_ID=$POSTHOG_CLI_PROJECT_ID \
POSTHOG_CLI_HOST=$POSTHOG_CLI_HOST
RUN npm run build # now sees the upload credentials
With no CI wiring the image, tell the user to pass them when they build: docker build --build-arg POSTHOG_CLI_API_KEY=… --build-arg POSTHOG_CLI_PROJECT_ID=… --build-arg POSTHOG_CLI_HOST=… .ARG/ENV for the non-secret project ID and host:
# syntax=docker/dockerfile:1
FROM node:22-slim
WORKDIR /app
# ...
ARG POSTHOG_CLI_PROJECT_ID
ARG POSTHOG_CLI_HOST
ENV POSTHOG_CLI_PROJECT_ID=$POSTHOG_CLI_PROJECT_ID \
POSTHOG_CLI_HOST=$POSTHOG_CLI_HOST
RUN --mount=type=secret,id=POSTHOG_CLI_API_KEY,env=POSTHOG_CLI_API_KEY \
npm run build
Build with docker build --secret id=POSTHOG_CLI_API_KEY,env=POSTHOG_CLI_API_KEY --build-arg POSTHOG_CLI_PROJECT_ID=… --build-arg POSTHOG_CLI_HOST=… .. In docker/build-push-action, pass the key through the secrets: input (POSTHOG_CLI_API_KEY=${{ secrets.POSTHOG_CLI_API_KEY }}) instead of build-args:. The env= attribute on --mount needs a current BuildKit — keep the # syntax=docker/dockerfile:1 line; on engines too old for it, read the file form instead: RUN --mount=type=secret,id=POSTHOG_CLI_API_KEY POSTHOG_CLI_API_KEY=$(cat /run/secrets/POSTHOG_CLI_API_KEY) npm run build.env: on that step:
- name: Build
run: npm run build
env:
POSTHOG_CLI_API_KEY: ${{ secrets.POSTHOG_CLI_API_KEY }}
POSTHOG_CLI_PROJECT_ID: ${{ secrets.POSTHOG_CLI_PROJECT_ID }}
POSTHOG_CLI_HOST: ${{ secrets.POSTHOG_CLI_HOST }}
docker build / docker/build-push-action Add the ARG/ENV to the Dockerfile build stage (above), then forward the creds as build args. Raw takes ; takes a multi-line input — :
posthog-cli links the release to a git commit, branch and repo so Error Tracking can show which deploy an error came from. It auto-detects that from the CI's git env vars or a local .git directory — you never touch the CLI invocation itself (it's usually baked into npm run build or a bundler plugin), you just make the git context available in the build environment. A docker build is where this breaks: it sees neither the env vars nor .git (the same boundary credentials hit), so the release ends up linked to nothing unless you forward the vars in.
ARG and promote it to ENV — ARG alone isn't visible to the CLI's env lookup. That's all auto-detection needs; no CLI flags, no .git.build-args: |
GITHUB_ACTIONS=true
GITHUB_SHA=${{ github.sha }}
GITHUB_REF_NAME=${{ github.ref_name }}
GITHUB_REPOSITORY=${{ github.repository }}
GITHUB_SERVER_URL=${{ github.server_url }}
Then in the build stage, declare each as ARG and re-export it as ENV before the build runs.Optionally add a temporary, clearly-labeled affordance that captures one test exception, so you can confirm errors arrive in Error Tracking with a source-resolved stack trace after the next production build. Always remove it afterwards.
throw. Throwing depends on the global error handler and shows a dev overlay; a direct capture is deterministic across platforms.posthog.captureException(new Error("PostHog source maps test")).GET /__posthog-test-error) on the existing server that calls posthog.captureException(new Error("PostHog source maps test")) and returns 200. With no HTTP layer, add the capture to the existing entry script where the client is initialised rather than creating a new file. Tell the user the exact command/URL to hit.Button on the main screen whose onPress calls posthog.captureException(new Error("PostHog source maps test")).Button on the launcher Activity whose onClick handler is exactly:
import com.posthog.PostHog
PostHog.captureException(Throwable("PostHog source maps test"))
Test flow — the upload only runs on the minified release variant: ./gradlew installRelease (or Android Studio ▸ Build Variants ▸ release, then Run), launch the app, tap the button. It's an event, not a crash — the app keeps running.Button on the root view (SwiftUI) or UIButton on the root view controller (UIKit), handler:
do {
throw NSError(domain: "PostHogSourceMapTest", code: 1,
userInfo: [NSLocalizedDescriptionKey: "Source map upload test error"])
} catch {
PostHogSDK.shared.captureException(error)
}
(capture() takes an event-name String, not an Error.) Test flow — give the user these steps verbatim, everything happens in Xcode (no xcodebuild): 1) In Xcode: Edit Scheme ▸ Run ▸ Build Configuration ▸ Release, then Run — the Release build uploads dSYMs automatically. 2) Tap the "" button in the app. It's an event, not a crash — no debugger-detach or relaunch steps.ElevatedButton on the home widget whose onPressed calls Posthog().captureException(Exception("PostHog source maps test")).Confirm the upload landed and report what changed.
Dockerfile, workflow, pipeline config) and spell out every manual follow-up — e.g. the secrets the user must add in their CI provider's settings before their next deploy, or the note that their build path couldn't be traced.PATHnpm install -gposthog-android SDK — never reuse the SDK version in id("com.posthog.android") version "…"..js.map files — follow the platform reference for the exact build hook.tasks.withType(PostHogCliExecTask).configureEach { … }POSTHOG_CLI_*.envENVdocker inspectENVdocker historyRUNARGENVsecrets. Inside a .github/actions/*/action.yml only ${{ inputs.* }} is available. Add an inputs: entry per credential, reference ${{ inputs.* }} there, and pass ${{ secrets.* }} from the calling workflow's with: block.script:. ${{ secrets.* }} is substituted by Actions before the script is sent, so the value travels with the script.withCredentials, …), and cross the same boundaries the same way — Docker builds still need --build-arg, SSH sessions still need inline vars.docker build--build-argdocker/build-push-actionbuild-args:with: block, don't add a second step- name: Build and push image
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
build-args: |
POSTHOG_CLI_API_KEY=${{ secrets.POSTHOG_CLI_API_KEY }}
POSTHOG_CLI_PROJECT_ID=${{ secrets.POSTHOG_CLI_PROJECT_ID }}
POSTHOG_CLI_HOST=${{ secrets.POSTHOG_CLI_HOST }}
uses: ./.github/actions/build-and-push, the build-push-action lives in that action's action.yml, which can't see secrets. Thread them through as inputs. In .github/actions/build-and-push/action.yml:
inputs:
posthog-cli-api-key:
required: true
posthog-cli-project-id:
required: true
posthog-cli-host:
required: true
runs:
using: composite
steps:
- uses: docker/build-push-action@v6
with:
# ...existing context/file/push/tags...
build-args: |
POSTHOG_CLI_API_KEY=${{ inputs.posthog-cli-api-key }}
POSTHOG_CLI_PROJECT_ID=${{ inputs.posthog-cli-project-id }}
POSTHOG_CLI_HOST=${{ inputs.posthog-cli-host }}
Then pass the secrets from the calling workflow's with: block:
- uses: ./.github/actions/build-and-push
with:
# ...existing inputs...
posthog-cli-api-key: ${{ secrets.POSTHOG_CLI_API_KEY }}
posthog-cli-project-id: ${{ secrets.POSTHOG_CLI_PROJECT_ID }}
posthog-cli-host: ${{ secrets.POSTHOG_CLI_HOST }}
appleboy/ssh-action with git pull && npm run build), set the vars inline right before the build command inside the script: — mirror however the script already passes runtime vars:
- uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.DEPLOY_HOST }}
# ...
script: |
cd /srv/app && git pull --ff-only origin main && npm ci
POSTHOG_CLI_API_KEY="${{ secrets.POSTHOG_CLI_API_KEY }}" \
POSTHOG_CLI_PROJECT_ID="${{ secrets.POSTHOG_CLI_PROJECT_ID }}" \
POSTHOG_CLI_HOST="${{ secrets.POSTHOG_CLI_HOST }}" \
npm run build
.gitlab-ci.yml) Project CI/CD variables are injected into every job's environment automatically, so a job that runs the build inline (script: - npm run build) needs no functional YAML change — no variables: block, and do NOT add a script line that writes the variables into a .env file (printf … > .env, echo … >> .env, etc.); the build already sees them as environment variables, which take precedence over any dotenv file. DO leave a comment on the build job so the requirement is visible in the repo, not only in your hand-off:
build:
stage: build
# PostHog source map upload: this job needs POSTHOG_CLI_API_KEY,
# POSTHOG_CLI_PROJECT_ID and POSTHOG_CLI_HOST available as CI/CD
# variables (Settings → CI/CD → Variables); GitLab injects them into
# the job automatically. Mark them Masked — but Protected only if this
# job runs exclusively on protected branches, otherwise feature-branch
# builds fail with missing credentials.
script:
- npm ci
- npm run build
Then tell the user to add those variables in Settings → CI/CD → Variables and the next pipeline picks them up. Edits beyond the comment are only needed when a boundary is crossed: a job that runs docker build must forward them (--build-arg POSTHOG_CLI_API_KEY="$POSTHOG_CLI_API_KEY" …) into the Dockerfile's build stage (see the Dockerfile example), and a job that builds over SSH must set them inline before the remote build command, exactly like the SSH example above.Dockerfile, no CI config, and no build step you can trace: make no CI changes — do not author a new workflow, pipeline, or deploy file to fill the gap. Tell the user that wherever their production build command runs, it must have the upload credentials (POSTHOG_CLI_* / POSTHOG_*) available as environment variables, or maps won't upload on deploy. If part of the path is still recognisable — e.g. a Dockerfile built by an unfamiliar CI — wire the layers you do recognise and tell the user exactly what the remaining layer must pass in (e.g. the --build-arg flags).