Configure and explain web analytics
Outcome
Section titled “Outcome”You will configure Google Analytics 4 (GA4) for one controlled local test. The application will send one custom task_created event to a teacher-provided training property only after an explicit test-mode action. You will verify the event path and explain what its event count can and cannot show.
Why this matters
Section titled “Why this matters”Analytics turns selected interactions into recorded events and reports. A report is useful only when the team can explain the question, event trigger, parameters, collection boundary, exclusions, and limits. More collection does not make a better measurement plan.
What you will practice
- Trace data from an application action through a tag, web data stream, property, DebugView, and report.
- Define one measurement question before adding collection code.
- Distinguish an event, event parameter, dimension, and metric.
- Configure a GA4 training tag that is inactive during normal application use.
- Send one custom event exactly once after a successful state change.
- Exclude task text, identifiers, personal data, and invalid attempts from the custom event.
- Verify source, Network, DebugView, and regression evidence without treating synthetic data as real visitor behavior.
- Explain the decisions that an event count supports and the questions it cannot answer.
What is new and what is reused
Section titled “What is new and what is reused”- New: Web analytics, measurement question, measurement plan, GA4 account, property, web data stream, Measurement ID, Google tag, custom event, event parameter, dimension, metric, DebugView, Realtime, external data transfer, synthetic analytics data, and controlled test mode.
- Reused: The task tracker, successful submit path, functions, state mutation, event listeners, derived values, DevTools Network and Console, evidence statuses, regression testing, private GitHub repository, quality board, and publication boundary.
Starting point
Before you start
- The final technical SEO commit, technical-seo-report.md, interactive-test-report.md, and quality-plan.md.
- The tested task application with one successful handleTaskSubmit path and a documented reset procedure.
- The private GitHub repository and the final-regression project item still in Ready.
- A teacher-provided GA4 training property, web data stream, Measurement ID, and property access for DebugView.
- Written approval to send synthetic lesson events from localhost to that training property.
- VS Code, a local HTTP server, a current browser with DevTools, Git, and access to the official GA4 documentation.
- Current state
- The application has functional, SEO, and source evidence. It does not yet have an approved measurement question, external-data boundary, analytics configuration, event test, interpretation, or final regression after analytics changes.
- First action
- Create analytics-measurement-plan.md and record the teacher-provided property name, stream name, Measurement ID, access level, approved test window, and data-removal or expiry owner.
- First checkpoint
- The plan names one answerable question, one custom event, its exact successful trigger, excluded data, tool owner, test boundary, evidence statuses, and the decision that the result could support.
- Help trigger
- Use the recovery note or ask for help if no approved training property exists, the property or stream owner is unclear, the tag loads during normal use, an event contains task text or personal data, one action sends several custom events, DebugView shows the wrong property, or analytics code changes application behavior.
Required result
Section titled “Required result”You have completed the lesson when:
analytics-measurement-plan.mdidentifies the tested commit, application question, tool owner, training property, web data stream, Measurement ID, test window, synthetic-data boundary, and cleanup or expiry owner;- the teacher confirms that the property is for training, enhanced measurement is disabled for this exercise, and real visitors must not use the test route;
- the plan defines one
task_createdcustom event and no second required custom event; - the event fires once after a valid task record enters state and does not fire for empty or whitespace-only input;
- the event sends only
input_length_bandandtest_contextas custom parameters; - no task text, task ID, name, email address, user ID, school record, free-form error, URL query value, or other personal or sensitive value becomes a custom parameter;
- the normal local URL does not load the Google tag or send analytics requests;
- the test URL works only on
localhostor127.0.0.1, requiresanalytics_test=1, and uses the exact teacher-provided Measurement ID; - the GA4 configuration disables automatic page-view sending, Google signals, and ad-personalization signals for the exercise;
- the custom event uses debug mode and an approved synthetic task value;
- DevTools shows one expected tag load and one
task_createdcollection request after the successful test action; - DebugView shows the matching event name and allowed parameter values in the correct training property;
- the plan explains the complete data path, the
event_namedimension, the Event count metric, and the difference between DebugView and a processed report; - the interpretation makes no claim about real visitors, unique people, intent, satisfaction, accessibility, causation, or production performance;
- the normal application URL passes the previous scripted paths, keyboard, focus, state, narrow, zoom, source, and Console regression checks;
- the final-regression project item links to the analytics and regression evidence and moves to
Doneonly after those checks pass; - the final tested commit is recorded in the reports; and
- the plan and verified source changes are committed and pushed to the private repository.
Confirm the training boundary before configuration
Section titled “Confirm the training boundary before configuration”Do not create a personal analytics property or connect a production school property to complete the lesson. Ask the teacher for this preflight record:
| Required fact | Evidence to record |
|---|---|
| Property owner | Named school or training owner |
| Property purpose | Level 2 synthetic analytics practice |
| Web data stream | Exact stream name and approved source context |
| Measurement ID | Exact G- identifier from that stream |
| Learner access | Access that can open the correct property and DebugView |
| Automatic collection | Enhanced measurement disabled for this controlled exercise |
| Allowed data | Synthetic event and the two named custom parameters only |
| Test window | Start and end condition for lesson events |
| Cleanup or expiry | Named owner and action after the exercise |
If any fact is missing, set configuration evidence to Blocked, name the missing fact and owner, and give the plan to the teacher. You can write the measurement plan and study the GA4 demo account while you wait, but you cannot claim that you configured and verified the training tool.
Explain the tool before adding it
Section titled “Explain the tool before adding it”Use one stable term for each part of the data path:
| Part | Role in this lesson |
|---|---|
| Application action | A valid form submission adds a synthetic task record to state |
| Google tag | Browser code queues and sends the selected event to Google Analytics |
| Measurement ID | Identifies the teacher-provided web data stream destination |
| Web data stream | Receives web measurement data for one GA4 property |
| Property | Holds the configured measurement data and reports |
| Event | Names an observed action, such as task_created |
| Event parameter | Adds bounded context, such as input_length_band: "short" |
| Dimension | Describes data by a category, such as event name |
| Metric | Counts or measures data, such as Event count |
| DebugView | Shows debug-enabled events and parameters for implementation checks |
| Realtime or standard report | Aggregates received data for analysis, subject to processing and report rules |
The required data path is:
approved local test action -> successful state change -> task_created event -> Google tag -> teacher web data stream -> training property -> DebugView evidence -> bounded interpretationAn event parameter collects context. A dimension or metric makes collected data available for analysis in a report. DebugView can show a custom parameter during implementation even when no custom dimension has been created for standard reporting.
Checkpoint: The tool and data boundary are approved
- What now works
- The plan names the approved property, stream, Measurement ID, access, test window, cleanup owner, one measurement question, one custom event, two allowed custom parameters, exclusions, and expected evidence.
- Files changed
analytics-measurement-plan.md- What remains
- Add the controlled tag configuration and connect the event to the confirmed successful state change.
- Next action
- Keep the normal application URL open, clear the Network log, and prove that no Google Analytics request occurs before you edit app.js.
- If it does not work
- If property details or approval are missing, record Blocked and send the exact preflight table to the teacher. Do not create or reuse an unapproved property.
Write the measurement plan
Section titled “Write the measurement plan”Add this structure to analytics-measurement-plan.md:
# Analytics measurement plan: Project task tracker
## Tested build and environment
- Starting commit:- Local URL:- Browser and version:- Operating system:- Test date:
## Ownership and external-data boundary
- Tool: Google Analytics 4- Property owner:- Training property:- Web data stream:- Measurement ID:- Approved test window:- Enhanced measurement confirmed off by:- Cleanup or expiry owner:- Real visitor collection: Not approved
## Measurement question
- Question: How often does an approved synthetic test session create a valid task?- Decision supported: Confirm whether the selected successful action reaches the training property once.- Decision not supported: Any product, visitor, or production decision.
## Event specification
Add the required event table.
## Source, Network, and DebugView evidence
Add the required test matrix.
## Interpretation and limits
- Observed event count:- What the evidence shows:- What the evidence does not show:- Configuration issues:- Next action:
## Final regression and handoff
- Final tested commit:- Interactive regression result:- Technical SEO regression result:- Normal-mode no-collection result:- Final-regression project item:- Open limits:Use these statuses: Not run, Pass, Issue, Blocked, and Accepted limitation.
Specify one event
Section titled “Specify one event”Add this table under Event specification:
| Field | Required value |
|---|---|
| Measurement question | How often does an approved synthetic test session create a valid task? |
| Event name | task_created |
| Trigger | One valid submit has added one task object to state.tasks |
| Non-trigger | Empty or whitespace-only input; page load; field focus; button click before validation |
input_length_band |
short, medium, or long, derived from trimmed text length |
test_context |
level_2_lesson |
| Excluded values | Complete task text, task ID, user ID, names, contact details, free-form strings |
| Expected event count | Zero for invalid input; one for one successful synthetic submit |
| Intended report dimension | Event name |
| Intended report metric | Event count |
task_created is a custom event because no required GA4 recommended event describes creating an in-memory practice task. The name starts with a letter and uses lowercase letters and an underscore. Keep the same spelling and case in source, Network evidence, DebugView, and the plan.
Audit the data before collection
Section titled “Audit the data before collection”The custom event must not include taskName. A task field accepts free-form text, so a tester could enter a real name, email address, school detail, or another personal value. Derive a bounded length category locally and discard the text from the analytics path.
GA4 can add standard web context to collected events, including page and device information. This is why the exercise uses an approved training property, a synthetic tester, a local-only switch, and no real visitor traffic. The two custom parameters are not the complete provider data inventory.
Do not send:
- the task text or a substring of it;
- the task record ID;
- the validation error text;
- an email address, name, phone number, account identifier, or school record;
- a user ID, device fingerprint, or persistent project-specific identifier;
- the full query string as a custom parameter; or
- a value because it might be useful later.
Record the normal-mode baseline
Section titled “Record the normal-mode baseline”Before adding analytics code:
- Start the application through its documented local HTTP method.
- Open the normal URL without
analytics_test=1. - Clear the Network and Console logs.
- Submit one synthetic valid task and one invalid value.
- Confirm the application behaves as documented.
- Filter Network for
googletagmanager,google-analytics, andanalytics.google. - Record that no analytics request exists in the starting build.
After implementation, you will repeat the same normal-mode check. The unchanged result proves that the training integration remains inactive during ordinary use.
Add a controlled GA4 training configuration
Section titled “Add a controlled GA4 training configuration”Add this block near the start of app.js, after the initial state and before the event handlers. Replace the placeholder only with the exact teacher-provided training Measurement ID.
const TRAINING_MEASUREMENT_ID = "G-REPLACE_WITH_TEACHER_ID";const LOCAL_ANALYTICS_HOSTS = new Set(["localhost", "127.0.0.1"]);
const analyticsTestRequested = new URLSearchParams( window.location.search,).get("analytics_test") === "1";
const hasTrainingMeasurementId = /^G-[A-Z0-9]+$/.test( TRAINING_MEASUREMENT_ID,) && !TRAINING_MEASUREMENT_ID.includes("REPLACE");
const analyticsTestEnabled = ( LOCAL_ANALYTICS_HOSTS.has(window.location.hostname) && analyticsTestRequested && hasTrainingMeasurementId);
function gtag() { window.dataLayer.push(arguments);}
function startAnalyticsTest() { if (!analyticsTestEnabled) { return; }
window.dataLayer = window.dataLayer || []; window.gtag = gtag;
gtag("js", new Date()); gtag("config", TRAINING_MEASUREMENT_ID, { allow_ad_personalization_signals: false, allow_google_signals: false, debug_mode: true, page_location: `${window.location.origin}${window.location.pathname}`, send_page_view: false, });
const analyticsScript = document.createElement("script"); analyticsScript.async = true; analyticsScript.src = ( "https://www.googletagmanager.com/gtag/js?id=" + encodeURIComponent(TRAINING_MEASUREMENT_ID) ); document.head.append(analyticsScript);}This configuration has three independent gates:
- the host must be
localhostor127.0.0.1; - the URL must contain
analytics_test=1; and - the Measurement ID must have a non-placeholder
G-format.
The function returns before it creates dataLayer, configures GA4, or loads the external script when any gate is false. send_page_view: false prevents the configuration command from sending its default page-view event. The teacher also disables enhanced measurement for this training stream so it does not add page-change collection outside this source setting.
The two advertising settings reduce the exercise scope. They do not replace the property-owner review or a production privacy implementation.
Start the controlled configuration once
Section titled “Start the controlled configuration once”Call the setup function once after its declaration:
startAnalyticsTest();Do not call it from a render function or submit handler. Repeated setup calls can make the data path harder to reason about and test.
Confirm the gates before adding an event
Section titled “Confirm the gates before adding an event”Run these source and browser checks:
| ID | Condition | Expected result |
|---|---|---|
ANA-01 |
Normal localhost URL | No tag script, data layer, or analytics request |
ANA-02 |
Localhost with analytics_test=1 and placeholder ID |
No tag load; configuration remains incomplete |
ANA-03 |
Non-local host with query and training ID | No tag load |
ANA-04 |
Localhost with query and approved training ID | One Google tag script request; application still works |
Use the normal URL for ANA-01. For ANA-02 and ANA-04, change only the condition named in the row. Do not publish the page to create ANA-03; inspect the guard and, when useful, test the expression in the Console with a synthetic host string.
Checkpoint: Normal use does not start analytics
- What now works
- The normal URL makes no analytics request, the source requires all three gates, the approved test URL loads one training tag, and the task tracker still passes its starting-state and primary-action checks.
- Files changed
app.js, analytics-measurement-plan.md- What remains
- Derive an allowed parameter and send task_created exactly once after the successful state change.
- Next action
- Add recordTaskCreated after startAnalyticsTest, then connect one call to the valid submit path.
- If it does not work
- If the tag loads in normal mode, close the test route, restore the last passing commit, and trace each gate before testing any event.
Derive a bounded parameter
Section titled “Derive a bounded parameter”Add this function after startAnalyticsTest:
function recordTaskCreated(taskName) { if (!analyticsTestEnabled) { return; }
let inputLengthBand = "long";
if (taskName.length <= 24) { inputLengthBand = "short"; } else if (taskName.length <= 60) { inputLengthBand = "medium"; }
gtag("event", "task_created", { input_length_band: inputLengthBand, test_context: "level_2_lesson", });}The function reads the already trimmed text only to choose one of three labels. It does not add the text to dataLayer or the event parameters.
| Trimmed length | Parameter value |
|---|---|
| 1–24 characters | short |
| 25–60 characters | medium |
| 61 or more characters | long |
This is a practice classification, not a claim that one band is better. The categories make the parameter bounded and testable.
Connect the event to the successful state change
Section titled “Connect the event to the successful state change”Find handleTaskSubmit. Keep the invalid-input return. Add one call only after the task object enters state:
state.tasks.push({ id: state.nextTaskId, name: taskName, completed: false,});state.nextTaskId += 1;
recordTaskCreated(taskName);
taskNameInput.removeAttribute("aria-invalid");taskError.textContent = "";taskForm.reset();renderTasks();taskNameInput.focus();Do not attach analytics to the submit button’s click event. A form can be submitted with the keyboard, and a click can occur before validation succeeds. The established submit handler already knows whether state changed.
The analytics call follows the confirmed mutation. It does not decide whether the task is valid and does not change the state or DOM. When analytics is disabled or its external script is blocked, the core task cycle still runs.
Trace one valid and one invalid path
Section titled “Trace one valid and one invalid path”invalid submit -> validation message -> return -> no state change -> no task_created event
valid submit -> trim and validate -> add one task object -> derive one length band -> queue one task_created event in test mode -> render the changed stateSearch the complete source for task_created and recordTaskCreated(. There must be one event definition and one production call site. Documentation strings and the function declaration can create additional text matches; identify the one executable call inside the successful handler.
Verify the event in four layers
Section titled “Verify the event in four layers”Add this matrix under Source, Network, and DebugView evidence:
| ID | Check | Expected result | Actual result | Status and evidence |
|---|---|---|---|---|
EVT-01 |
Inspect successful handler | One call occurs after one state mutation | Not run | Not run |
EVT-02 |
Inspect event parameters | Only length band and lesson context are custom values | Not run | Not run |
EVT-03 |
Use normal URL and submit valid data | Application changes; no analytics request | Not run | Not run |
EVT-04 |
Use test URL and submit empty data | Validation appears; no task_created request |
Not run | Not run |
EVT-05 |
Submit one short synthetic task | One new task and one task_created request |
Not run | Not run |
EVT-06 |
Inspect collection request | Correct Measurement ID, event name, and allowed values; no task text | Not run | Not run |
EVT-07 |
Inspect correct DebugView | Matching event and parameters appear in training property | Not run | Not run |
EVT-08 |
Reload normal URL | Tag is absent; required application reset still works | Not run | Not run |
Use an approved synthetic task such as Run analytics test. Do not enter a real person’s task, name, email address, or school detail.
-
Open the correct property before generating data.
In GA4, use the property selector and compare the property and stream names with the plan. Open Admin → DebugView. Interface labels can change; use the current official DebugView guide when the route differs.
-
Open the controlled local route.
Use the application’s reported localhost URL and add
?analytics_test=1. Do not add the parameter to a public or preview URL. -
Clear the browser evidence.
Open DevTools. Clear Network and Console. Enable Network log preservation only when a reload would otherwise remove evidence. Filter for
gtag/jsandg/collect. -
Prove the non-trigger.
Submit an empty value. Confirm the application validation, unchanged task count, and absence of a new
task_createdcollection request. -
Prove the one event.
Submit Run analytics test once. Confirm one new task, one new
task_createdrequest, no JavaScript error, and no duplicate custom-event request. -
Inspect the request.
Confirm the destination uses the teacher’s Measurement ID. Find the event name and the two allowed parameter values. Search the request details for the complete synthetic task text and confirm it is absent.
-
Inspect DebugView.
Select the current debug device when required. Open
task_createdand confirminput_length_band: shortandtest_context: level_2_lesson. Record the observed time and property. Other provider-generated events can exist; count the custom event by its exact name. -
Return to normal mode.
Remove the query string, reload, clear Network, and repeat one valid submit. Confirm the application works and no new analytics request occurs.
DebugView is implementation evidence. A collection request proves that the browser attempted to send data. DebugView proves that the selected property received and classified the debug event. Neither proves that a future production configuration is complete or compliant.
If the request or DebugView evidence is missing
Section titled “If the request or DebugView evidence is missing”Change one condition at a time:
| Symptom | Check first |
|---|---|
| No tag script request | Local host, query parameter, placeholder guard, and setup call |
| Tag loads but event request is absent | Successful handler call site, Console error, and content blocker |
| Several custom-event requests | Duplicate handler, duplicate call site, or repeated setup |
| Wrong property receives the event | Measurement ID in source and selected GA4 property |
| Request exists but DebugView is empty | debug_mode, correct debug device, access, property, and processing delay |
| Task text appears in the request | Event object or another analytics call that passes free-form input |
| Application fails when the tag is blocked | Analytics code owns a core state, validation, or render decision |
Preserve the first failing condition and form a specific cause hypothesis before editing. Do not disable a privacy control or browser security setting on a managed device without teacher approval.
Checkpoint: One synthetic action reaches the training property
- What now works
- Invalid input sends no custom event; one approved valid submit produces one task, one task_created request, and one matching DebugView event with only the two allowed custom parameters. Normal mode remains inactive.
- Files changed
app.js, analytics-measurement-plan.md, interactive-test-report.md- What remains
- Interpret the count, run the full final regression, close the planned quality item, and record the final commit.
- Next action
- Write What the evidence shows and What the evidence does not show before reading any standard report.
- If it does not work
- If evidence disagrees between source, Network, and DebugView, record each layer separately. Resume at the earliest layer that does not match its expected result.
Explain what the data means
Section titled “Explain what the data means”For this event:
- Event name is a dimension: it groups records under
task_created. - Event count is a metric: it totals how many matching events GA4 processed for the selected scope and time.
input_length_bandis an event parameter: it adds one bounded category to each event.- DebugView shows implementation details for debug-enabled events.
- Realtime and standard reports aggregate data and can use different processing windows and report rules.
One approved submit should produce one custom event. Therefore, one matching DebugView event supports this limited statement:
In the recorded synthetic test, the configured successful path sent one
task_createdevent with the expected bounded parameters to the teacher’s training property.
It does not support these statements:
- one event equals one unique person;
- real visitors can or will complete the task;
- a missing event proves a visitor abandoned the form;
- the application is useful, understandable, accessible, or satisfying;
- the event caused a later action;
- all browsers, privacy settings, blockers, or network conditions behave the same way;
- a training result predicts production traffic; or
- collecting more fields would make the conclusion more accurate.
Connect the result to a decision
Section titled “Connect the result to a decision”The required measurement supports one implementation decision: whether the selected successful action is connected to the intended training stream exactly once.
It does not yet support a product decision. A product question would need an approved public context, a defined visitor group, a suitable comparison or target, adequate data quality, a privacy-approved collection plan, and evidence beyond one synthetic session.
Explain the tool in your own words
Section titled “Explain the tool in your own words”Add a short explanation to the plan that answers:
- What does the Google tag do in this application?
- What does the Measurement ID select?
- When does
task_createdfire, and when does it not fire? - Which custom values leave the application?
- Why is Event count different from a count of unique people?
- What is DebugView evidence useful for?
- Which decision can the result support?
- Which important questions remain unanswered?
Use the exact source and recorded evidence. Do not copy a general marketing description of analytics.
Run the final application regression
Section titled “Run the final application regression”Move QA: Run final regression and review evidence from Ready to In progress. Keep every other item out of In progress.
Use the normal URL without analytics_test=1 for the final product regression. Follow the reset procedure and rerun:
- the fifteen scripted cases from
interactive-test-report.md; - empty, whitespace-only, repeated, long, and HTML-looking input paths;
- keyboard-only form and checkbox paths with visible and restored focus;
- state, list, summary, and status-message agreement;
- the primary interaction near 320 CSS pixels and at 200% zoom;
- saved-source and rendered-DOM checks from the technical SEO report;
- HTML, CSS, startup, and interaction Console checks; and
- the normal-mode Network check for no Google tag or analytics collection request.
Record each actual result against the final source commit. Do not reuse the earlier Pass values without executing the conditions after the analytics change.
If a regression fails:
- keep the final-regression item
In progress; - reproduce the same condition twice;
- record the earliest incorrect state or request;
- test one cause hypothesis;
- repair the smallest confirmed cause;
- rerun the failed condition, connected primary path, and normal-mode analytics guard; and
- update the evidence before changing the board status.
Move the item to Done only when the final source passes. Link analytics-measurement-plan.md, interactive-test-report.md, technical-seo-report.md, and the final commit in the private issue or project item. The board should then have no open required Level 2 quality item.
Complete the handoff record
Section titled “Complete the handoff record”End analytics-measurement-plan.md with a result in this form:
## Final result
- Analytics configuration: Pass for approved local training mode- Normal-mode collection: No Google tag or analytics request observed- Custom event: task_created- Allowed custom parameters: input_length_band and test_context- Synthetic test result: One valid action produced one matching event- Invalid test result: No custom event- DebugView property and time:- Final regression: Pass against final tested commit- Production analytics: Not approved and not configured- Cleanup or expiry owner:- Final tested commit:- Open limits: Synthetic single-session evidence; no real visitor conclusionRemove the query parameter after the test. Do not leave a browser tab generating repeated events. Follow the teacher’s cleanup or expiry instruction; do not delete property data or change property settings unless the owner authorized that action.
Common problems
Section titled “Common problems”The tag loads on the normal URL
Section titled “The tag loads on the normal URL”Stop the test. Restore all three gates and confirm that the early return occurs before dataLayer and the external script are created.
An event fires when the button is clicked
Section titled “An event fires when the button is clicked”Move the analytics call out of the button click path. Keep one call after successful validation and state mutation in the form submit handler.
One submit creates several events
Section titled “One submit creates several events”Search for duplicate call sites and duplicate submit listeners. Confirm setup and listener registration occur once, outside render functions.
Task text appears in the request
Section titled “Task text appears in the request”Remove the free-form value from every analytics call. Keep only the locally derived length band. Retest with synthetic text and inspect the complete request again.
DebugView shows a different property
Section titled “DebugView shows a different property”Stop generating events. Compare the source Measurement ID with the plan and the selected property. Resume only after the teacher confirms the correct training destination.
The report shows more events than the one test
Section titled “The report shows more events than the one test”Filter by the exact event name, test context, time, and debug device when available. Other learners and provider-generated events can share the training property. Do not interpret the property total as one learner’s result.
A content blocker prevents the tag
Section titled “A content blocker prevents the tag”Record the environment and blocked request as evidence. Use a teacher-approved testing environment if one exists. Do not weaken a managed-device control without approval.
The application depends on analytics
Section titled “The application depends on analytics”Remove analytics from the state, validation, and render decisions. The application must remain functional when the integration is disabled, slow, or blocked.
Self-check
Section titled “Self-check”Self-check
Complete these checks against the required result.
- Confirm that the plan names the tool owner, training property, web data stream, Measurement ID, access, test window, automatic-collection state, and cleanup or expiry owner.
- Point to the one measurement question, one event definition, exact successful trigger, non-triggers, and supported implementation decision.
- Confirm that the normal application URL does not create dataLayer, load the Google tag, or send an analytics request.
- Confirm that all three gates are required: local host, analytics_test=1, and an approved non-placeholder G- identifier.
- Inspect the configuration and confirm that page-view sending, Google signals, and ad-personalization signals are disabled for the exercise.
- Submit empty and whitespace-only input in test mode and confirm that no task record and no task_created event appear.
- Submit Run analytics test once and confirm one new task, one custom collection request, and one matching DebugView event.
- Inspect the request and confirm that only input_length_band and test_context are custom parameters and the task text is absent.
- Explain event, parameter, dimension, metric, data stream, property, DebugView, and report through this implementation.
- State what the event count shows and why it does not count unique people or prove a real visitor outcome.
- Rerun the complete application, accessibility, responsive, source, Console, and normal-mode collection checks against the final source.
- Confirm that the final-regression item is Done, the reports name the final tested commit, the training route is closed, and the working tree is clean.
Extension routes
Section titled “Extension routes”Complete the required result before choosing an extension. Extensions do not change the definition of done.
Official references
Section titled “Official references”- Set up Analytics for a website explains properties, web data streams, Measurement IDs, tags, and initial verification.
- Set up GA4 events explains event commands, names, parameters, and report destinations.
- GA4 event naming rules lists valid names and reserved values.
- GA4 configuration fields documents
send_page_viewand other configuration values. - Monitor events in DebugView explains debug mode and event inspection.
- Verify and troubleshoot a GA4 setup describes Network, Console, DebugView, and report checks.
- Avoid sending personally identifiable information states Google’s PII collection restriction.
- Try the Analytics demo account provides existing demo data for report practice.
Commit the completed measurement work
Section titled “Commit the completed measurement work”Review the complete diff before staging. Do not include screenshots with property access details, personal data, an API secret, or unrelated files.
git statusgit diffgit add app.js analytics-measurement-plan.md interactive-test-report.md technical-seo-report.md quality-plan.mdgit diff --stagedgit commit -m "Configure controlled analytics event"git pushStage only the files that actually changed. Record the final tested commit hash in the reports. If the hash record requires one small follow-up commit, identify which commit contains the tested application and which commit only updates the record.
Next step or safe stopping point
Section titled “Next step or safe stopping point”The lesson is complete when one approved synthetic action reaches the teacher’s training property exactly once, the normal application remains analytics-free, the data limits are explained, the final regression passes, and the quality board is closed.
Continue to Final project: Build, evaluate, and present a web application to apply the Level 2 interaction, CMS, responsive, animation, quality, SEO, and analytics work to the assessed product.
If you stop, leave the application on its normal URL and the repository in a committed state. Add this resume record to the plan: Last passing check; current evidence layer; active issue; property and stream names without credentials; next exact action; and the normal-mode collection result.