diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index 8ac26fb07cd..00000000000 --- a/docs/Makefile +++ /dev/null @@ -1,142 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html livehtml dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest install-local-python-deps - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " livehtml to make standalone HTML files and automatically rebuild them on change" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - @echo " install-local-python-deps to install Python dependencies for documentation building" - -clean: - -rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -livehtml: - sphinx-autobuild "$(SOURCEDIR)" "$(BUILDDIR)" --port 8100 --open-browser --delay 1 $(SPHINXOPTS) $(O) - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/playdoh.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/playdoh.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/playdoh" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/playdoh" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - make -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -install-local-python-deps: - pip install -r ../requirements/docs.txt diff --git a/docs/_static/.gitkeep b/docs/_static/.gitkeep deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/docs/_templates/.gitkeep b/docs/_templates/.gitkeep deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/docs/_templates/footer.html b/docs/_templates/footer.html deleted file mode 100644 index b3c8e289a26..00000000000 --- a/docs/_templates/footer.html +++ /dev/null @@ -1,53 +0,0 @@ -
- {% if (theme_prev_next_buttons_location == 'bottom' or theme_prev_next_buttons_location == 'both') and (next or prev) %} - - {% endif %} - -
- -
-

- {%- if show_copyright %} - {%- if hasdoc('copyright') %} - {% set path = pathto('copyright') %} - {% set copyright = copyright|e %} - © Copyright {{ copyright }} - {%- else %} - {% set copyright = copyright|e %} - © Copyright {{ copyright }} - {%- endif %} - {%- endif %} - - {%- if build_id and build_url %} - - Build - {{ build_id }}. - - {%- elif commit %} - - Revision {{ commit }}. - - {%- elif last_updated %} - - Last updated on {{ last_updated|e }}. - - {%- endif %} - -

-
- - {%- if show_sphinx %} - Built with Sphinx using a theme provided by Read the Docs. - {%- endif %} - - {%- block extrafooter %} {% endblock %} - -
- \ No newline at end of file diff --git a/docs/abtest.md b/docs/abtest.md new file mode 100644 index 00000000000..1e0d4eb8577 --- /dev/null +++ b/docs/abtest.md @@ -0,0 +1,255 @@ +--- +title: A/B Testing +--- + +# Convert experiments + +Conversion rate optimization (CRO) experiments on bedrock can be run +using a third-party tool called [Convert](https://convert.com). Convert +experiments are for relatively simple multivariate experiments, such as +testing changes to headlines, images, or button copy. + +The Convert script is not included in part of bedrock's base bundle for +performance reasons. To use Convert on a page, you can load the script +behind a feature flag, which can be turned on / off for only the +duration of an experiment. The script should be loaded inside the +`experiments` block in your template: + +``` jinja +{% block experiments %} + {% if switch('experiment-convert-page-name', ['en-US']) %} + {{ js_bundle('convert') }} + {% endif %} +{% endblock %} +``` + +Convert A/B tests can be implemented using the [Convert +dashboard](https://convert.com) and editor. Convert experiments should +be coded and tested against staging, before being reviewed and scheduled +to run in production. + +## QA for Convert experiments + +The process for QA'ing Convert experiments is as follows: + +1. Bedrock feature switch should be activated on staging. +2. Experiment is built and configured to run on + `https://www.allizom.org/*` +3. In the Github issue for an experiment, someone will request review + by an engineer. + +An engineer reviewing the experiment will: + +1. Verify that the experiment is not configured to run on + (production) yet. +2. Activate the experiment to run on stage. + +During review, the engineer will compare the following to the experiment +plan: + +1. The experiment's logic. +2. Any JS included (in Convert editor's JS field). +3. Any CSS included (in Convert editor's CSS field). +4. The target audience is configured. +5. The goals are configured. +6. The distribution percentages are configured. +7. The target URLs are configured. + +Once the engineer is satisfied, the engineer (or someone else with write +privileges) will: + +1. Add `https://www.mozilla.org/*` to the list of URLs the experiment + can run on. +2. Reset the experiment (eliminating any data gathered during QA). +3. Enable the bedrock feature switch in production. +4. Activate (or schedule) the experiment. + +After an experiment is finished, the feature switch should be +deactivated in production. + +!!! note + + `*` should be replaced by the exact URL pathname for the experiment page. + +# Traffic Cop experiments + +More complex experiments, such as those that feature full page +redesigns, or multi-page user flows, should be implemented using +[Traffic Cop](https://github.com/mozmeao/trafficcop/). Traffic Cop small +javascript library which will direct site traffic to different variants +in a/b experiments and make sure a visitor always sees the same +variation. + +It's possible to test more than 2 variants. + +Traffic Cop sends users to experiments and then we use Google Analytics +(GA) to analyze which variation is more successful. (If the user has +DNT enabled they do not +participate in experiments.) + +All a/b tests should have a [mana +page](https://mana.mozilla.org/wiki/display/EN/Details+of+experiments+by+mozilla.org+team) +detailing the experiment and recording the results. + +## Coding the variants + +Traffic cop supports two methods of a/b testing. Executing different on +page javascript or redirecting to the same URL with a query string +appended. We mostly use the redirect method in bedrock. This makes +testing easier. + +Create a [variation +view](http://bedrock.readthedocs.io/en/latest/coding.html#variation-views) +for the a/b test. + +The view can handle the URL redirect in one of two ways: + +1. the same page, with some different content based on the + [variation]{.title-ref} variable +2. a totally different page + +## Content variation + +Useful for small focused tests. + +This is explained on the [variation +view](http://bedrock.readthedocs.io/en/latest/coding.html#variation-views) +page. + +## New page + +Useful for large page changes where content and assets are dramatically +different. + +Create the variant page like you would a new page. Make sure it is +`noindex` and does not have a `canonical` URL. + +``` jinja +{% block canonical_urls %}{% endblock %} +``` + +Configure as explained on the [variation +view](http://bedrock.readthedocs.io/en/latest/coding.html#variation-views) +page. + +## Traffic Cop + +Create a .js file where you initialize Traffic Cop and include that in +the experiments block in the template that will be doing the +redirection. Wrap the extra js include in a +[switch](http://bedrock.readthedocs.io/en/latest/install.html#feature-flipping-aka-switches). + +``` jinja +{% block experiments %} + {% if switch('experiment-berlin-video', ['de']) %} + {{ js_bundle('firefox_new_berlin_experiment') }} + {% endif %} +{% endblock %} +``` + +## Switches + +See the traffic cop section of the [switch +docs](http://bedrock.readthedocs.io/en/latest/install.html#feature-flipping-aka-switches) +for instructions. + +## Recording the data + +!!! note + + If you are measuring installs as part of your experiment be sure to + configure [custom stub + attribution](https://bedrock.readthedocs.io/en/latest/firefox-stub-attribution.html#measuring-campaigns-and-experiments) + as well. + +Including the `data-ex-variant` and `data-ex-name` in the analytics +reporting will add the test to an auto generated report in +GA. The variable values may be provided by the analytics team. + +``` javascript +if (href.indexOf('v=a') !== -1) { + window.dataLayer.push({ + 'data-ex-variant': 'de-page', + 'data-ex-name': 'Berlin-Campaign-Landing-Page' + }); +} else if (href.indexOf('v=b') !== -1) { + window.dataLayer.push({ + 'data-ex-variant': 'campaign-page', + 'data-ex-name': 'Berlin-Campaign-Landing-Page' + }); +} +``` + +Make sure any buttons and interaction which are being compared as part +of the test and will report into GA. + +## Viewing the data + +The `data-ex-name` and `data-ex-variant` are encoded in Google Analytics +as custom dimensions 69 and 70. + +Create a custom report. + +Set the "Metrics Group" to include Sessions. Configure additional +metrics depending on what the experiment was measuring (downloads, +events, etc.) + +Set the "Dimension Drilldowns to have cd69 in the top position and cd70 +in the drilldown position. + +View the custom report and drilldown into the experiment with the +matching name. + +## Tests + +Write some tests for your a/b test. This could be simple or complex +depending on the experiment. + +Some things to consider checking: + +- Requests for the default (non variant) page call the correct + template. +- Requests for a variant page call the correct template. +- Locales excluded from the test call the correct (default) template. + +## A/B Test PRs that might have useful code to reuse + +- +- +- +- +- +- + +# Avoiding experiment collisions + +To ensure that Traffic Cop doesn't overwrite data from any other +externally controlled experiments (for example Ad campaign tests, or +in-product Firefox experiments), you can use the experiment-utils helper +to decide whether or not Traffic Cop should initiate. + +``` javascript +import TrafficCop = from '@mozmeao/trafficcop'; +import { isApprovedToRun } from '../../base/experiment-utils.es6'; + +if (isApprovedToRun()) { + const cop = new TrafficCop({ + id: 'experiment-name', + variations: { + 'entrypoint_experiment=experiment-name&entrypoint_variation=a': 10, + 'entrypoint_experiment=experiment-name&entrypoint_variation=b': 10 + } + }); + + cop.init(); +} +``` + +The `isApprovedToRun()` function will check the page URL's query +parameters against a list of well-known experimental params, and return +`false` if any of those params are found. It will also check for some +other cases where we do not want to run experiments, such as if the page +is being opened in an automated testing environment. + +*[DNT]: Do Not Track +*[GA]: Google Analytics diff --git a/docs/abtest.rst b/docs/abtest.rst deleted file mode 100644 index 896ef1c4fa8..00000000000 --- a/docs/abtest.rst +++ /dev/null @@ -1,245 +0,0 @@ -.. This Source Code Form is subject to the terms of the Mozilla Public -.. License, v. 2.0. If a copy of the MPL was not distributed with this -.. file, You can obtain one at https://mozilla.org/MPL/2.0/. - -.. _ab_testing: - -=========== -A/B Testing -=========== - -Convert experiments -------------------- - -Conversion rate optimization (CRO) experiments on bedrock can be run using a -third-party tool called `Convert `_. Convert experiments -are for relatively simple multivariate experiments, such as testing changes -to headlines, images, or button copy. - -The Convert script is not included in part of bedrock's base bundle for -performance reasons. To use Convert on a page, you can load the script -behind a feature flag, which can be turned on / off for only the duration -of an experiment. The script should be loaded inside the ``experiments`` -block in your template: - -.. code-block:: jinja - - {% block experiments %} - {% if switch('experiment-convert-page-name', ['en-US']) %} - {{ js_bundle('convert') }} - {% endif %} - {% endblock %} - -Convert A/B tests can be implemented using the `Convert dashboard -`_ and editor. Convert experiments should be coded and -tested against staging, before being reviewed and scheduled to run in -production. - -QA for Convert experiments -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The process for QA'ing Convert experiments is as follows: - -#. Bedrock feature switch should be activated on staging. -#. Experiment is built and configured to run on ``https://www.allizom.org/*`` -#. In the Github issue for an experiment, someone will request review by an engineer. - -An engineer reviewing the experiment will: - -#. Verify that the experiment is not configured to run on https://www.mozilla.org/ (production) yet. -#. Activate the experiment to run on stage. - -During review, the engineer will compare the following to the experiment plan: - -#. The experiment’s logic. -#. Any JS included (in Convert editor’s JS field). -#. Any CSS included (in Convert editor’s CSS field). -#. The target audience is configured. -#. The goals are configured. -#. The distribution percentages are configured. -#. The target URLs are configured. - -Once the engineer is satisfied, the engineer (or someone else with write privileges) will: - -#. Add ``https://www.mozilla.org/*`` to the list of URLs the experiment can run on. -#. Reset the experiment (eliminating any data gathered during QA). -#. Enable the bedrock feature switch in production. -#. Activate (or schedule) the experiment. - -After an experiment is finished, the feature switch should be deactivated in production. - -.. Note:: - - ``*`` should be replaced by the exact URL pathname for the experiment page. - -Traffic Cop experiments ------------------------ - -More complex experiments, such as those that feature full page redesigns, or -multi-page user flows, should be implemented using `Traffic Cop -`_. Traffic Cop small javascript -library which will direct site traffic to different variants in a/b -experiments and make sure a visitor always sees the same variation. - -It's possible to test more than 2 variants. - -Traffic Cop sends users to experiments and then we use Google Analytics (GA) to -analyze which variation is more successful. (If the user has :abbr:`DNT (Do Not Track)` -enabled they do not participate in experiments.) - -All a/b tests should have a `mana page `_ -detailing the experiment and recording the results. - -Coding the variants -~~~~~~~~~~~~~~~~~~~ - -Traffic cop supports two methods of a/b testing. Executing different on page -javascript or redirecting to the same URL with a query string appended. We -mostly use the redirect method in bedrock. This makes testing easier. - -Create a `variation view `_ -for the a/b test. - -The view can handle the URL redirect in one of two ways: - -#. the same page, with some different content based on the `variation` variable -#. a totally different page - -Content variation -~~~~~~~~~~~~~~~~~ - -Useful for small focused tests. - -This is explained on the `variation view `_ -page. - -New page -~~~~~~~~ - -Useful for large page changes where content and assets are dramatically -different. - -Create the variant page like you would a new page. Make sure it is ``noindex`` -and does not have a ``canonical`` URL. - -.. code-block:: jinja - - {% block canonical_urls %}{% endblock %} - - -Configure as explained on the `variation view `_ -page. - -Traffic Cop -~~~~~~~~~~~ - -Create a .js file where you initialize Traffic Cop and include that in the -experiments block in the template that will be doing the redirection. Wrap the -extra js include in a `switch `_. - -.. code-block:: jinja - - {% block experiments %} - {% if switch('experiment-berlin-video', ['de']) %} - {{ js_bundle('firefox_new_berlin_experiment') }} - {% endif %} - {% endblock %} - -Switches -~~~~~~~~ - -See the traffic cop section of the `switch docs `_ for instructions. - -Recording the data -~~~~~~~~~~~~~~~~~~ - -.. Note:: - - If you are measuring installs as part of your experiment be sure to configure `custom stub attribution `_ as well. - -Including the ``data-ex-variant`` and ``data-ex-name`` in the analytics -reporting will add the test to an auto generated report in :abbr:`GA (Google Analytics)`. -The variable values may be provided by the analytics team. - -.. code-block:: javascript - - if (href.indexOf('v=a') !== -1) { - window.dataLayer.push({ - 'data-ex-variant': 'de-page', - 'data-ex-name': 'Berlin-Campaign-Landing-Page' - }); - } else if (href.indexOf('v=b') !== -1) { - window.dataLayer.push({ - 'data-ex-variant': 'campaign-page', - 'data-ex-name': 'Berlin-Campaign-Landing-Page' - }); - } - -Make sure any buttons and interaction which are being compared as part of the -test and will report into :abbr:`GA (Google Analytics)`. - -Viewing the data -~~~~~~~~~~~~~~~~~~ - -The ``data-ex-name`` and ``data-ex-variant`` are encoded in Google Analytics as custom dimensions 69 and 70. - -Create a custom report. - -Set the "Metrics Group" to include Sessions. Configure additional metrics depending on what the experiment was measuring (downloads, events, etc.) - -Set the "Dimension Drilldowns to have cd69 in the top position and cd70 in the drilldown position. - -View the custom report and drilldown into the experiment with the matching name. - -Tests -~~~~~ - -Write some tests for your a/b test. This could be simple or complex depending -on the experiment. - -Some things to consider checking: - -- Requests for the default (non variant) page call the correct template. -- Requests for a variant page call the correct template. -- Locales excluded from the test call the correct (default) template. - -A/B Test PRs that might have useful code to reuse -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- https://github.com/mozilla/bedrock/pull/5736/files -- https://github.com/mozilla/bedrock/pull/4645/files -- https://github.com/mozilla/bedrock/pull/5925/files -- https://github.com/mozilla/bedrock/pull/5443/files -- https://github.com/mozilla/bedrock/pull/5492/files -- https://github.com/mozilla/bedrock/pull/5499/files - -Avoiding experiment collisions ------------------------------- - -To ensure that Traffic Cop doesn't overwrite data from any other externally -controlled experiments (for example Ad campaign tests, or in-product Firefox -experiments), you can use the experiment-utils helper to decide whether or -not Traffic Cop should initiate. - -.. code-block:: javascript - - import TrafficCop = from '@mozmeao/trafficcop'; - import { isApprovedToRun } from '../../base/experiment-utils.es6'; - - if (isApprovedToRun()) { - const cop = new TrafficCop({ - id: 'experiment-name', - variations: { - 'entrypoint_experiment=experiment-name&entrypoint_variation=a': 10, - 'entrypoint_experiment=experiment-name&entrypoint_variation=b': 10 - } - }); - - cop.init(); - } - -The ``isApprovedToRun()`` function will check the page URL's query parameters -against a list of well-known experimental params, and return ``false`` if -any of those params are found. It will also check for some other cases where -we do not want to run experiments, such as if the page is being opened in -an automated testing environment. diff --git a/docs/architectural-decisions.md b/docs/architectural-decisions.md new file mode 100644 index 00000000000..4404e2e8d55 --- /dev/null +++ b/docs/architectural-decisions.md @@ -0,0 +1,12 @@ +--- +title: Architectural Decision Records +--- + +We record major architectural decisions for bedrock in Architecture +Decision Records (ADR), as [described by Michael +Nygard](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions). +Below is the list of our current ADRs. + +::: {.toctree maxdepth="1" glob=""} +architecture/decisions/\* +::: diff --git a/docs/architectural-decisions.rst b/docs/architectural-decisions.rst deleted file mode 100644 index 063a6d90197..00000000000 --- a/docs/architectural-decisions.rst +++ /dev/null @@ -1,19 +0,0 @@ -.. This Source Code Form is subject to the terms of the Mozilla Public -.. License, v. 2.0. If a copy of the MPL was not distributed with this -.. file, You can obtain one at https://mozilla.org/MPL/2.0/. - -.. _architectural-decisions: - -============================== -Architectural Decision Records -============================== - -We record major architectural decisions for bedrock in Architecture Decision Records (ADR), -as `described by Michael Nygard `_. -Below is the list of our current ADRs. - -.. toctree:: - :maxdepth: 1 - :glob: - - architecture/decisions/* diff --git a/docs/architecture/decisions/0001-record-architecture-decisions.md b/docs/architecture/decisions/0001-record-architecture-decisions.md index f98969ef659..08a0b78930e 100644 --- a/docs/architecture/decisions/0001-record-architecture-decisions.md +++ b/docs/architecture/decisions/0001-record-architecture-decisions.md @@ -1,4 +1,3 @@ -# 1. Record architecture decisions Date: 2019-01-07 diff --git a/docs/architecture/decisions/0002-move-ci-cd-pipelines-to-gitlab.md b/docs/architecture/decisions/0002-move-ci-cd-pipelines-to-gitlab.md index bcce9635fe6..a46741249ea 100644 --- a/docs/architecture/decisions/0002-move-ci-cd-pipelines-to-gitlab.md +++ b/docs/architecture/decisions/0002-move-ci-cd-pipelines-to-gitlab.md @@ -1,4 +1,3 @@ -# 2. Move CI/CD Pipelines to Gitlab Date: 2019-10-09 diff --git a/docs/architecture/decisions/0003-use-cloudflare-workers-and-convert-for-multi-variant-testing.md b/docs/architecture/decisions/0003-use-cloudflare-workers-and-convert-for-multi-variant-testing.md index 5908269df8f..32045980d40 100644 --- a/docs/architecture/decisions/0003-use-cloudflare-workers-and-convert-for-multi-variant-testing.md +++ b/docs/architecture/decisions/0003-use-cloudflare-workers-and-convert-for-multi-variant-testing.md @@ -1,4 +1,3 @@ -# 3. Use Cloudflare Workers and Convert for multi-variant testing Date: 2019-10-09 diff --git a/docs/architecture/decisions/0004-use-fluent-for-localization.md b/docs/architecture/decisions/0004-use-fluent-for-localization.md index d5f0eef93de..898de47fbc0 100644 --- a/docs/architecture/decisions/0004-use-fluent-for-localization.md +++ b/docs/architecture/decisions/0004-use-fluent-for-localization.md @@ -1,4 +1,3 @@ -# 4. Use Fluent For Localization Date: 2019-12-16 diff --git a/docs/architecture/decisions/0005-use-a-single-docker-image-for-all-deployments.md b/docs/architecture/decisions/0005-use-a-single-docker-image-for-all-deployments.md index 5e09a170dbe..f3d1ec5472d 100644 --- a/docs/architecture/decisions/0005-use-a-single-docker-image-for-all-deployments.md +++ b/docs/architecture/decisions/0005-use-a-single-docker-image-for-all-deployments.md @@ -1,4 +1,3 @@ -# 5. Use a Single Docker Image For All Deployments Date: 2020-07-07 diff --git a/docs/architecture/decisions/0006-revise-tooling-for-python-dependency-management.md b/docs/architecture/decisions/0006-revise-tooling-for-python-dependency-management.md index d0aad1e0f97..6a0bd684b90 100644 --- a/docs/architecture/decisions/0006-revise-tooling-for-python-dependency-management.md +++ b/docs/architecture/decisions/0006-revise-tooling-for-python-dependency-management.md @@ -1,4 +1,3 @@ -# 6. Revise tooling for Python dependency management Date: 2022-02-25 diff --git a/docs/architecture/decisions/0007-further-revise-tooling-for-python-dependency-management.md b/docs/architecture/decisions/0007-further-revise-tooling-for-python-dependency-management.md index 609471b3c72..8d8e25c86a5 100644 --- a/docs/architecture/decisions/0007-further-revise-tooling-for-python-dependency-management.md +++ b/docs/architecture/decisions/0007-further-revise-tooling-for-python-dependency-management.md @@ -1,4 +1,3 @@ -# 7. Further revise tooling for Python dependency management Date: 2022-03-02 diff --git a/docs/architecture/decisions/0008-move-demos-to-gcp.md b/docs/architecture/decisions/0008-move-demos-to-gcp.md index c793faa2d11..3dfbf1edf33 100644 --- a/docs/architecture/decisions/0008-move-demos-to-gcp.md +++ b/docs/architecture/decisions/0008-move-demos-to-gcp.md @@ -1,4 +1,3 @@ -# 8. Move Demos To GCP Date: 2022-07-14 diff --git a/docs/architecture/decisions/0009-use-manage-contentful-migrations.md b/docs/architecture/decisions/0009-use-manage-contentful-migrations.md index b4b9de49da9..9ca589286e1 100644 --- a/docs/architecture/decisions/0009-use-manage-contentful-migrations.md +++ b/docs/architecture/decisions/0009-use-manage-contentful-migrations.md @@ -1,4 +1,3 @@ -# 9. Manage Contentful schema state via migrations Date: 2022-09-09 diff --git a/docs/architecture/decisions/0010-move-ci-cd-to-github-actions.md b/docs/architecture/decisions/0010-move-ci-cd-to-github-actions.md index 4dd79fe1a50..6763045abe3 100644 --- a/docs/architecture/decisions/0010-move-ci-cd-to-github-actions.md +++ b/docs/architecture/decisions/0010-move-ci-cd-to-github-actions.md @@ -1,4 +1,3 @@ -# 10. Move CI to Github Actions for Unit and Integration tests Date: 2023-04-06 diff --git a/docs/architecture/decisions/0011-use-statsd-for-metrics-collection.md b/docs/architecture/decisions/0011-use-statsd-for-metrics-collection.md index 7bba11d0691..9184333a28a 100644 --- a/docs/architecture/decisions/0011-use-statsd-for-metrics-collection.md +++ b/docs/architecture/decisions/0011-use-statsd-for-metrics-collection.md @@ -1,4 +1,3 @@ -# 11. Use StatsD for metrics collection Date: 2023-05-19 @@ -80,7 +79,7 @@ captured at relevant points within the application. specific functions or code blocks within bedrock. * **Define Consistent Metric Names**: Choose meaningful and consistent names for our metrics. This helps in easily understanding and - interpreting the collected data. + interpreting the collected data. * **Timing Metrics**: Use timing metrics to measure the duration of specific operations. This can include measuring the time taken to render a template, execute a database query, or process a request. StatsD provides diff --git a/docs/attribution.rst b/docs/attribution.md similarity index 50% rename from docs/attribution.rst rename to docs/attribution.md index 23cb8dbc9ae..633e58a88bd 100644 --- a/docs/attribution.rst +++ b/docs/attribution.md @@ -1,12 +1,6 @@ -.. This Source Code Form is subject to the terms of the Mozilla Public -.. License, v. 2.0. If a copy of the MPL was not distributed with this -.. file, You can obtain one at https://mozilla.org/MPL/2.0/. - -.. _attribution: - -=========== -Attribution -=========== +--- +title: Attribution +--- Attribution is the practice of recording the main touch points that a website visitor encounters on their path to downloading or signing up @@ -15,11 +9,5 @@ sometimes across multiple properties, but the goal is to end up with informative data that tells us where the user of a product initially came from, and what their journey looked like along the way. -These documents define how attribution works for the different -products on our websites. - -.. toctree:: - :maxdepth: 1 - :glob: - - attribution/* +These documents define how attribution works for the different products +on our websites. diff --git a/docs/attribution/0001-analytics.md b/docs/attribution/0001-analytics.md new file mode 100644 index 00000000000..9f42045216c --- /dev/null +++ b/docs/attribution/0001-analytics.md @@ -0,0 +1,478 @@ +--- +title: Mozorg analytics +--- + +# Google Tag Manager (GTM) + +In mozorg mode, bedrock uses [Google Tag Manager +(GTM)](https://tagmanager.google.com/) to manage and organize its +[Google Analytics](https://analytics.google.com/) solution. + +GTM is a tag management system that allows for easy implementation of Google +Analytics (GA) tags and other 3rd party marketing tags in a nice GUI +experience. Tags can be added, updated, or removed directly from the +GUI. GTM allows for a "one source of truth" approach to managing an +analytics solution in that all analytics tracking can be inside GTM. + +Bedrock's GTM solution is CSP compliant +and does not allow for the injection of custom HTML or JavaScript but +all tags use built in templates to minimize any chance of introducing a +bug into Bedrock. + +## The GTM DataLayer + +How an application communicates with GTM is via the `dataLayer` object, +which is a simple JavaScript array GTM instantiates on the page. Bedrock +will send messages to the `dataLayer` object by means of pushing an +object literal onto the `dataLayer`. GTM creates an abstract data model +from these pushed objects that consists of the most recent value for all +keys that have been pushed to the `dataLayer`. + +The only reserved key in an object pushed to the `dataLayer` is `event` +which will cause GTM to evaluate the firing conditions for all tag +triggers. + +## DataLayer push example + +If we wanted to track clicks on a carousel and capture what the image +was that was clicked, we might write a dataLayer push like this: + +``` javascript +dataLayer.push({ + 'event': 'carousel-click', + 'image': 'house' +}); +``` + +In the dataLayer push there is an event value to have GTM evaluate the +firing conditions for tag triggers, making it possible to fire a tag off +the dataLayer push. The event value is descriptive to the user action so +it's clear to someone coming in later what the dataLayer push +signifies. There is also an image property to capture the image that is +clicked, in this example it's the house picture. + +In GTM, a tag could be setup to fire when the event `carousel-click` is +pushed to the dataLayer and could consume the image value to pass on +what image was clicked. + +## The Core DataLayer object + +For the passing of contextual data on the user and page to GTM, we've +created what we call the Core DataLayer Object. This object passes as +soon as all required API calls for contextual data have completed. +Unless there is a significant delay to when data will be available, +please pass all contextual or meta data on the user or page here that +you want to make available to GTM. + +### Conditional banners + +When a banner is shown: + +``` javascript +dataLayer.push({ + 'eLabel': 'Banner Impression', + 'data-banner-name': '', //ex. Fb-Video-Compat + 'data-banner-impression': '1', + 'event': 'non-interaction' +}); +``` + +When an element in the banner is clicked: + +``` javascript +dataLayer.push({ + 'eLabel': 'Banner Clickthrough', + 'data-banner-name': '', //ex. Fb-Video-Compat + 'data-banner-click': '1', + 'event': 'in-page-interaction' +}); +``` + +When a banner is dismissed: + +``` javascript +dataLayer.push({ + 'eLabel': 'Banner Dismissal', + 'data-banner-name': '', //ex. Fb-Video-Compat + 'data-banner-dismissal': '1', + 'event': 'in-page-interaction' +}); +``` + +### A/B tests + +``` javascript +if(href.indexOf('v=a') !== -1) { + window.dataLayer.push({ + 'data-ex-variant': 'de-page', + 'data-ex-name': 'Berlin-Campaign-Landing-Page' + }); +} else if (href.indexOf('v=b') !== -1) { + window.dataLayer.push({ + 'data-ex-variant': 'campaign-page', + 'data-ex-name': 'Berlin-Campaign-Landing-Page' + }); +} +``` + +## GTM listeners & data attributes + +GTM also uses click and form submit listeners to gather context on what +is happening on the page. Listeners push to the dataLayer data on the +specific element that triggered the event, along with the element object +itself. + +Since GTM listeners pass the interacted element object to the dataLayer, +the use of data attributes works very well when trying to identify key +elements that you want to be tracked and for storing data on that +element to be passed into Google Analytics. We use data attributes to +track clicks on all downloads, buttons elements, and nav, footer, and +CTA/button link elements. + +!!! tip "Important" + + When adding any new elements to a Bedrock page, please follow the below + guidelines to ensure accurate analytics tracking. + +For all generic CTA links and `