diff --git a/.gitignore b/.gitignore index f88f355..2de78b1 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,5 @@ resources/.arch-internal-preview.css .arch-internal-preview.css node_modules/ dist/ -yarn.lock \ No newline at end of file +yarn.lock +.idea \ No newline at end of file diff --git a/CONTRIBUTE.md b/CONTRIBUTE.md new file mode 100644 index 0000000..115db10 --- /dev/null +++ b/CONTRIBUTE.md @@ -0,0 +1,115 @@ +# Contribute to react-tag-commander + +We're delighted that you're interested in contributing to react-tag-commander! This document is intended to outline the process and guidelines for contributing to this repository. We want to make contributing to this project as easy and transparent as possible. + +## Getting Started + +1. **Fork the repository** + +Start by forking the repository on GitHub. This will create a personal copy for you to work on. + +2. **Clone your fork** + +Clone your fork to your local machine. Replace `your-username` with your GitHub username. + +```bash +git clone https://github.com/your-username/react-tag-commander.git +``` + +3. **Set up remote upstream** + +Add the original repository as an upstream remote to your local repository. + +```bash +git remote add upstream https://github.com/CommandersAct/react-tag-commander.git +``` + +4. **Install dependencies** + +Navigate to the project directory and install its dependencies. + +```bash +cd react-tag-commander +npm install +``` + +## Making Changes + +1. **Create a branch** + +Create a new branch for your changes. + +```bash +git checkout -b feature/my-new-feature +``` + +2. **Make your changes** + +Edit, add, or delete files as necessary for your contribution. + +3. **Follow the coding standards** + +Ensure your code adheres to the coding standards used throughout the project. + +4. **Write tests** + +If you're adding new functionality, please write tests to accompany it. + +5. **Run the tests** + +Ensure all tests pass before submitting your changes. + +```bash +npm run test +``` + +6. **Document your changes** + +Update the documentation to reflect any changes you have made. + +7. **Update the Sample App** + +Update the `tag-commander-sample-app` to reflect any changes you have made. Ensure that it is still running and add new examples if possible to illustrate your changes. + + +## Submitting Changes + +1. **Commit your changes** + +Commit your changes with a clear and descriptive commit message. + +```bash +git commit -m "Add a brief description of your changes" +``` + +2. **Fetch upstream changes** + +Fetch any recent changes from the upstream master branch. + +```bash +git fetch upstream +``` + +3. **Rebase your branch** + +Rebase your branch on top of the upstream master. + +```bash +git rebase upstream/master +``` + +4. **Push your changes** + +Push your changes to your fork. + +```bash +git push origin feature/my-new-feature +``` + +5. **Create a pull request** + +Go to your fork on GitHub and create a pull request against the [CommandersAct/react-tag-commander](https://github.com/CommandersAct/react-tag-commander) 's master branch. + +## Reporting Issues + +If you find any bugs or have a feature request, please create an issue on GitHub using the issue tracker. diff --git a/README.md b/README.md index 11d05ba..fcd7678 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,8 @@ -# React-Tag-Commander Documentation +# react-tag-commander -Integrate Tag Commander with your React applications seamlessly using the `react-tag-commander` wrapper. +Integrate CommandersAct's tag container with your React applications seamlessly using the `react-tag-commander` wrapper. -- [Official Tag Commander website](https://www.commandersact.com/fr/produits/tagcommander/) -- **Note**: Familiarize yourself with [Tag Commander's primary documentation](https://community.commandersact.com/tagcommander/) before proceeding. +- **Note**: Familiarize yourself with [CommandersAct's tag container's primary documentation](https://doc.commandersact.com/features/sources/sources-catalog/web/containers) before proceeding. ## Table of Contents - [Features](#features) @@ -12,18 +11,20 @@ Integrate Tag Commander with your React applications seamlessly using the `react - [Container Management](#container-management) - [Variable Management](#variable-management) - [Events](#events) -- [Reloading Containers](#reloading-containers) + - [Reloading Containers](#reloading-containers) +- [Server-side Rendering (SSR)](#server-side-rendering) - [Sample App](#sample-app) - [License](#license) - [Development](#development) +- [Contribute](#contribute) -## Features +## Features - Automatic page tracking - Event triggering - Supports multiple containers -## Installation and Quick Start +## Installation and Quick Start ### Installation @@ -69,75 +70,90 @@ Integrate Tag Commander with your React applications seamlessly using the `react import React from "react"; import TC_Wrapper from "react-tag-commander"; -const wrapper = TC_Wrapper.getInstance(); - function App() { + const [tcReady, setTcReady] = useState(false); + + useEffect(() => { + const wrapper = TC_Wrapper.getInstance(); + Promise.all([ + wrapper.addContainer('container_head', '/tag-commander-head.js', 'head'), + wrapper.addContainer('container_body', '/tag-commander-body.js', 'body') + ]).then(() => { + setIsReady(true); + }); + }, []); + + return ( tcReady ?
Containers loaded
:
Now loading
); +} +``` +## Methods - const [tcReady, setTcReady] = useState(false); +Many methods are asynchronous. If you want to ensure that a method has been executed before continuing, you can use the `await` keyword. Please check the function definition to see if it is asynchronous. - useEffect(() => { - Promise.all([ - wrapper.addContainer('container_head', '/tag-commander-head.js', 'head'), - wrapper.addContainer('container_body', '/tag-commander-body.js', 'body') - ]).then(() => { - setIsReady(true); - }); - }, []); +### Container Management +```js +// Adding a container +await wrapper.addContainer('my-custom-id', '/url/to/container.js', 'head'); - return ( tcReady ?
Containers loaded
:
Now loading
); -} +// Removing a container +wrapper.removeContainer('my-custom-id'); ``` -# Methods - -Many methods are asynchronous. If you want to ensure that a method has been executed before continuing, you can use the `await` keyword. Please check the function definition to see if it is asynchronous. -## Container Management - ```js - // Adding a container - await wrapper.addContainer('my-custom-id', '/url/to/container.js', 'head'); +### Variable Management - // Removing a container - wrapper.removeContainer('my-custom-id'); - ``` +```js +// Set variables +await wrapper.setTcVars({ env_template : "shop", ... }); -## Variable Management - ```js - // Set variables - await wrapper.setTcVars({ env_template : "shop", ... }); +// Update a single variable +await wrapper.setTcVar('env_template', 'super_shop'); - // Update a single variable - await wrapper.setTcVar('env_template', 'super_shop'); +// Get a variable +const myVar = wrapper.getTcVar('VarKey'); - // Get a variable - const myVar = wrapper.getTcVar('VarKey'); +// Remove a variable +wrapper.removeTcVar('VarKey'); +``` - // Remove a variable - wrapper.removeTcVar('VarKey'); - ``` +### Events -## Events -- Refer to the [base documentation on events](https://community.commandersact.com/tagcommander/user-manual/container-management/events) for an understanding of events in general. +- Refer to the [base documentation on events](https://doc.commandersact.com/features/sources/sources-catalog/web/containers/user-guides-for-browser-side-platform/tags/rules/triggers) for an understanding of events in general. - The method "triggerEvent" is the new name of the old method "captureEvent"; an alias has been added to ensure backward compatibility. +```js +// Triggering an event +// eventLabel: Name of the event as defined in the container +// htmlElement: Calling context. Usually the HTML element on which the event is triggered, but it can be the component. +// data: event variables +await wrapper.triggerEvent(eventLabel, htmlElement, data); +``` - ```js - // Triggering an event - // eventLabel: Name of the event as defined in the container - // htmlElement: Calling context. Usually the HTML element on which the event is triggered, but it can be the component. - // data: event variables - await wrapper.triggerEvent(eventLabel, htmlElement, data); - ``` - -## Reloading Containers +### Reloading Containers -1. **Manual Reload**: Update your container after any variable change. - ```js - await wrapper.reloadContainer(siteId, containerId, options); - ``` +#### Manual Reload +Update your container after any variable change. +```js +await wrapper.reloadContainer(siteId, containerId, options); +``` -2. **On Route Change**: Utilize the `trackPageLoad` function for updating on route changes. +#### Exclusions +You can state an exclusion array to your options object like below. +```typescript +const options = { + exclusions: [ + 'datastorage', + 'deduplication', + 'internalvars', + 'privacy' + ] + }; +await wrapper.reloadContainer(siteId, containerId, options); +``` +Please see the [container's documentation](https://doc.commandersact.com/features/sources/sources-catalog/web/containers/setup-guides-for-developers/spa-implementation-guide#id-2.how-to-implement-tagcommander-in-an-spa-environment) for other options. +#### On Route Change +Utilize the `trackPageLoad` function for updating on route changes. ```js function SampleView() { @@ -152,7 +168,43 @@ function SampleView() { } ``` -## Sample App +## Server-side Rendering (SSR) + +`react-tag-commander` works seamlessly with frameworks utilizing Server-side Rendering (SSR) (for example [Next.js](https://nextjs.org/)). +However, the wrapper is interacting with the DOM objects `document` and `window`, which are not available on the server. +Therefore, you have to make sure that wrapper methods are only executed on the client-side. +This can be achieved by using hooks like `useEffect`, `useCallback` or `useState` or, executing it in a callback function that doesn't run on the server, for example the `submit` function of a form. + +Examples: +```js +// Throws an 'window is not defined' error, as the code is executed on the server and trackPageLoad interacts with the window object. +function SampleView() { + const wrapper = TC_Wrapper.getInstance(); + wrapper.trackPageLoad({tcVars: {page: 'home'}}) +} +``` +```js +// Works as the code is executed on the client only +function SampleView() { + useEffect(() => { + const wrapper = TC_Wrapper.getInstance(); + wrapper.trackPageLoad({tcVars: {page: 'home'}}) + }, []); +} +``` + +Another option is to check whether `window` is defined before executing a method. +```js +function SampleView() { + if (typeof window !== 'undefined') { + // client-side-only code + const wrapper = TC_Wrapper.getInstance(); + wrapper.trackPageLoad({tcVars: {page: 'home'}}) + } +} +``` + +## Sample App To help you with your implementation we provided a sample application. To run it clone the repo then run: ```bash @@ -161,15 +213,25 @@ yarn start ``` Then, visit [http://localhost:3000](http://localhost:3000). -## License -This module uses the [MIT License](http://revolunet.mit-license.org). Contributions are welcome. -## Development +# Development After forking, set up your environment: -1. ```npm install``` +```bash +npm install +``` Commands available: -1. ```gulp``` +```bash +gulp +``` + +# Contribute + +To contribute to this project, please read the [CONTRIBUTE.md](CONTRIBUTE.md) file. + +## License + +This module uses the [MIT License](http://revolunet.mit-license.org). Contributions are welcome. diff --git a/package.json b/package.json index 4cbcccf..1c546d2 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,8 @@ "name": "react-tag-commander", "version": "2.2.0", "main": "./src/index.js", - "repository": "https://github.com/TagCommander/react-tag-commander.git", - "author": "Lenoir jérémie", + "repository": "https://github.com/commandersact/react-tag-commander", + "author": "CommandersAct", "license": "MIT", "devDependencies": { "@babel/cli": "^7.22.9", diff --git a/tag-commander-sample-app/README.md b/tag-commander-sample-app/README.md index f065c6b..cd612f9 100644 --- a/tag-commander-sample-app/README.md +++ b/tag-commander-sample-app/README.md @@ -1,6 +1,6 @@ -# Tag Commander Sample App +# react-tag-commander sample app -Welcome to the Tag Commander Sample App! This is a demo app showcasing the npm package `react-tag-commander`. The app sets variables in Tag Commander, tracks pageviews, and provides a holistic summary on how the package can be used in a React Single Page Application (SPA). +Welcome to the CommandersAct's Tag Container sample app! This is a demo app showcasing the npm package `react-tag-commander`. The app sets variables in CommandersAct's tag container, tracks pageviews, and provides a holistic summary on how the package can be used in a React Single Page Application (SPA). ## Table of Contents @@ -12,11 +12,11 @@ Welcome to the Tag Commander Sample App! This is a demo app showcasing the npm p ## 1. Introduction -`react-tag-commander` is an npm package designed to facilitate the integration of Tag Commander in your React applications. This sample shop showcases its potential and demonstrates how it can be implemented in a real-world application scenario. +`react-tag-commander` is an npm package designed to facilitate the integration of CommandersAct's tag container in your React applications. This sample shop showcases its potential and demonstrates how it can be implemented in a real-world application scenario. ## 2. Features -- Set variables in Tag Commander dynamically. +- Set variables in CommandersAct's tag container dynamically. - Track pageviews efficiently. - Easily configure and customize your tags. diff --git a/tag-commander-sample-app/index.html b/tag-commander-sample-app/index.html index 3e13d67..78c41e9 100644 --- a/tag-commander-sample-app/index.html +++ b/tag-commander-sample-app/index.html @@ -4,7 +4,7 @@ - Tag Commander React Sample App + react-tag-commander sample app
diff --git a/tag-commander-sample-app/package-lock.json b/tag-commander-sample-app/package-lock.json index b578428..03b4bc7 100644 --- a/tag-commander-sample-app/package-lock.json +++ b/tag-commander-sample-app/package-lock.json @@ -7,11 +7,15 @@ "": { "name": "tag-commander-sample-app", "version": "1.0.0", + "license": "MIT", "dependencies": { + "highlight.js": "^11.9.0", + "marked": "^11.1.0", + "marked-highlight": "^2.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.14.2", - "react-tag-commander": "^1.1.1" + "react-tag-commander": "^2.0.0" }, "devDependencies": { "@testing-library/jest-dom": "^5.17.0", @@ -997,6 +1001,18 @@ "node": ">=6.0.0" } }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", @@ -1851,6 +1867,14 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "optional": true, + "peer": true + }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -1985,6 +2009,14 @@ "node": ">= 0.8" } }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "optional": true, + "peer": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -3067,6 +3099,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/highlight.js": { + "version": "11.9.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.9.0.tgz", + "integrity": "sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/html-encoding-sniffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", @@ -4071,6 +4111,25 @@ "node": ">=12" } }, + "node_modules/marked": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-11.1.0.tgz", + "integrity": "sha512-fvKJWAPEafVj1dwGwcPI5mBB/0pvViL6NlCbNDG1HOIRwwAU/jeMoFxfbRLuirO1wRH7m4yPvBqD/O1wyWvayw==", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/marked-highlight": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/marked-highlight/-/marked-highlight-2.1.0.tgz", + "integrity": "sha512-peBvgGZZqUw074Vy/N8Y7/6JQhSnR54/T0Ozq2/fAIBzcYfVfExFdQJptIhQxreR1elpwvJRrqhp6S/Prk8prA==", + "peerDependencies": { + "marked": ">=4 <12" + } + }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -4162,12 +4221,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/natives": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.6.tgz", - "integrity": "sha512-6+TDFewD4yxY14ptjKaS63GVdtKiES1pTPyxn9Jb0rBqPMZ7VcCiooEhPNsr+mqHtMGxa/5c/HhcC4uPEUw/nA==", - "deprecated": "This module relies on Node.js's internals and will break at some point. Do not use it, and update to graceful-fs@4.x." - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -4655,12 +4708,9 @@ } }, "node_modules/react-tag-commander": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/react-tag-commander/-/react-tag-commander-1.1.1.tgz", - "integrity": "sha512-Dg6b0Hos2vivHNtaP8vkpY6I5IEg+SNRQWHhX1p5RDCST7pwpnptCUXpxIXXK6UAKgCPdT0vpsPldTsuJfVBTw==", - "dependencies": { - "natives": "^1.1.6" - } + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/react-tag-commander/-/react-tag-commander-2.1.0.tgz", + "integrity": "sha512-JrT/xPgleF+k7LJvh/dRLfuQZKgZUPoyefyIDniY2FSq7a1Njl5K66iy0OxNn32xpMJbrFvFBqmC3tIIXXMMSQ==" }, "node_modules/redent": { "version": "3.0.0", @@ -4917,6 +4967,17 @@ "node": ">=8" } }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", @@ -4926,6 +4987,18 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -5113,6 +5186,26 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, + "node_modules/terser": { + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.26.0.tgz", + "integrity": "sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -6322,6 +6415,18 @@ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "dev": true }, + "@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, "@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", @@ -6986,6 +7091,14 @@ "update-browserslist-db": "^1.0.11" } }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "optional": true, + "peer": true + }, "cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -7076,6 +7189,14 @@ "delayed-stream": "~1.0.0" } }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "optional": true, + "peer": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -7890,6 +8011,11 @@ "has-symbols": "^1.0.2" } }, + "highlight.js": { + "version": "11.9.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.9.0.tgz", + "integrity": "sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==" + }, "html-encoding-sniffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", @@ -8621,6 +8747,17 @@ "@jridgewell/sourcemap-codec": "^1.4.15" } }, + "marked": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-11.1.0.tgz", + "integrity": "sha512-fvKJWAPEafVj1dwGwcPI5mBB/0pvViL6NlCbNDG1HOIRwwAU/jeMoFxfbRLuirO1wRH7m4yPvBqD/O1wyWvayw==" + }, + "marked-highlight": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/marked-highlight/-/marked-highlight-2.1.0.tgz", + "integrity": "sha512-peBvgGZZqUw074Vy/N8Y7/6JQhSnR54/T0Ozq2/fAIBzcYfVfExFdQJptIhQxreR1elpwvJRrqhp6S/Prk8prA==", + "requires": {} + }, "micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -8685,11 +8822,6 @@ "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", "dev": true }, - "natives": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.6.tgz", - "integrity": "sha512-6+TDFewD4yxY14ptjKaS63GVdtKiES1pTPyxn9Jb0rBqPMZ7VcCiooEhPNsr+mqHtMGxa/5c/HhcC4uPEUw/nA==" - }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -9033,12 +9165,9 @@ } }, "react-tag-commander": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/react-tag-commander/-/react-tag-commander-1.1.1.tgz", - "integrity": "sha512-Dg6b0Hos2vivHNtaP8vkpY6I5IEg+SNRQWHhX1p5RDCST7pwpnptCUXpxIXXK6UAKgCPdT0vpsPldTsuJfVBTw==", - "requires": { - "natives": "^1.1.6" - } + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/react-tag-commander/-/react-tag-commander-2.1.0.tgz", + "integrity": "sha512-JrT/xPgleF+k7LJvh/dRLfuQZKgZUPoyefyIDniY2FSq7a1Njl5K66iy0OxNn32xpMJbrFvFBqmC3tIIXXMMSQ==" }, "redent": { "version": "3.0.0", @@ -9219,12 +9348,32 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "peer": true + }, "source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", "dev": true }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -9366,6 +9515,20 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, + "terser": { + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.26.0.tgz", + "integrity": "sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + } + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", diff --git a/tag-commander-sample-app/package.json b/tag-commander-sample-app/package.json index 6a01f96..38975c3 100644 --- a/tag-commander-sample-app/package.json +++ b/tag-commander-sample-app/package.json @@ -1,9 +1,10 @@ { "name": "tag-commander-sample-app", - "private": true, "version": "1.0.0", - "repository": "https://github.com/commandersact/react-tag-commander.git", + "repository": "https://github.com/commandersact/react-tag-commander", "author": "CommandersAct", + "license": "MIT", + "private": true, "type": "module", "scripts": { "dev": "vite", @@ -14,6 +15,9 @@ "coverage": "vitest run --coverage" }, "dependencies": { + "highlight.js": "^11.9.0", + "marked": "^11.1.0", + "marked-highlight": "^2.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.14.2", diff --git a/tag-commander-sample-app/src/App.css b/tag-commander-sample-app/src/App.css index 5504a24..7e52bfb 100644 --- a/tag-commander-sample-app/src/App.css +++ b/tag-commander-sample-app/src/App.css @@ -1,5 +1,5 @@ body { - font-family: sans-serif; + font-family: "Avenir", Helvetica, Arial, sans-serif; margin: 0; padding: 0 } @@ -20,6 +20,7 @@ nav.navbar { line-height: 80px; padding: 0 0 0 30px; width: 100%; + position: fixed; z-index: 10 } @@ -64,42 +65,22 @@ main { background-color: #fff; box-shadow: 0 0 10px 0 #555; margin: 0 auto; - padding: 20px; + padding: 100px 20px 20px 20px; width: 1024px; z-index: 0 } nav + main { - padding: 100px 20px 20px + padding: 100px 20px 20px 20px; } pre { - background-color: #282828; + background-color: #1c1b1b; border-left: 20px solid #ed2186; box-shadow: 0 0 10px 0 #555; color: #fff; overflow-x: auto; - padding: 20px -} - -pre code.comment { - color: #009688 -} - -pre code.keyword { - color: #2196f3 -} - -pre code.varible { - color: #b3e5fc -} - -pre code.string { - color: #ff9800 -} - -pre code.method { - color: #ffc107 + padding: 10px } button.button { diff --git a/tag-commander-sample-app/src/App.jsx b/tag-commander-sample-app/src/App.jsx index 8916b1d..d42ead7 100644 --- a/tag-commander-sample-app/src/App.jsx +++ b/tag-commander-sample-app/src/App.jsx @@ -1,20 +1,19 @@ import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; import TC_Wrapper from 'react-tag-commander'; - -// Components +import { useEffect, useState } from "react"; import Navbar from "./components/layout/navbar/Navbar"; import Dashboard from "./components/dashboard/index.jsx"; import Home from "./components/home/index.jsx"; import Shop from "./components/shop/index.jsx"; -import { useEffect, useState } from "react"; -const wrapper = TC_Wrapper.getInstance(); -wrapper.setDebug(true); function App() { const [isReady, setIsReady] = useState(false); useEffect(() => { + const wrapper = TC_Wrapper.getInstance(); + wrapper.setDebug(true); + Promise.all([ wrapper.addContainer('container_head', '/tag-commander-head.js', 'head'), wrapper.addContainer('container_body', '/tag-commander-body.js', 'body'), diff --git a/tag-commander-sample-app/src/assets/cycle.png b/tag-commander-sample-app/src/assets/cycle.png new file mode 100644 index 0000000..c5af55e Binary files /dev/null and b/tag-commander-sample-app/src/assets/cycle.png differ diff --git a/tag-commander-sample-app/src/components/TcVars.jsx b/tag-commander-sample-app/src/components/TcVars.jsx index 4a8ed64..54803d9 100644 --- a/tag-commander-sample-app/src/components/TcVars.jsx +++ b/tag-commander-sample-app/src/components/TcVars.jsx @@ -2,11 +2,11 @@ import { useEffect } from 'react'; import TC_Wrapper from 'react-tag-commander'; function TcVars(props) { - const wrapper = TC_Wrapper.getInstance(); useEffect(() => { + const wrapper = TC_Wrapper.getInstance(); wrapper.setTcVars(props); - }, [props, wrapper]); // Depend on props and wrapper, although in most cases `wrapper` might not change. + }, [props]); } export default TcVars; diff --git a/tag-commander-sample-app/src/components/dashboard/index.jsx b/tag-commander-sample-app/src/components/dashboard/index.jsx index 2769fe1..d0b1f60 100644 --- a/tag-commander-sample-app/src/components/dashboard/index.jsx +++ b/tag-commander-sample-app/src/components/dashboard/index.jsx @@ -1,3 +1,4 @@ +import cycle from '../../assets/cycle.png' const Dashboard = () => { return (
@@ -26,7 +27,7 @@ const Dashboard = () => {
Tag lifecycle management
diff --git a/tag-commander-sample-app/src/components/home/index.jsx b/tag-commander-sample-app/src/components/home/index.jsx index b7e6dcc..e5c1e72 100644 --- a/tag-commander-sample-app/src/components/home/index.jsx +++ b/tag-commander-sample-app/src/components/home/index.jsx @@ -1,7 +1,25 @@ import { useEffect } from "react"; import TC_Wrapper from "react-tag-commander"; +import { markedHighlight } from "marked-highlight"; +import { Marked } from "marked"; +import hljs from "highlight.js"; +import "highlight.js/styles/stackoverflow-dark.css"; +import Readme from "../../../../README.md?raw" const Home = () => { + function getMarkdownText() { + const marked = new Marked( + markedHighlight({ + langPrefix: "hljs language-", + highlight(code, lang) { + const language = hljs.getLanguage(lang) ? lang : "plaintext"; + return hljs.highlight(code, { language }).value; + }, + }) + ); + return { __html: marked.parse(Readme)}; + } + useEffect(() => { const wrapper = TC_Wrapper.getInstance(); wrapper.trackPageLoad({tcReloadOnly: [ @@ -10,91 +28,11 @@ const Home = () => { }, []); return ( -
-

react-tag-commander Sample application

-

The loading and configuration

-

The main application configuration

-
-        import TC_Wrapper from 'react-tag-commander';
- const wrapper = TC_Wrapper.getInstance();
-
- {'// you need to provide URIS to load containers script. You can add as many container as you like'}
- {'// addContainer (id, uri, node)'}
- wrapper.addContainer('a_name_for_the_container_id', '/the/path/to/tag-commander-container.js', 'head');
-
- {'// but you can also remove them'}
- wrapper.removeContainer('my_tag_container_id');
-
- {'// you can set debug by setting this to true'}
- wrapper.setDebug(true);
-
- {'// you can track the url of your app by setting this, it will reload the containers on each page change'}
- wrapper.trackRoutes(true);
-
- -

- In the provider's method 'addContainer', The "node" parameter can either be set to 'body' or 'head', by default the container will be placed in the head. -

- -

The routes configuration

-

- If you have set wrapper.trackRoutes(true); in your application configuration, - you can configure witch container will be reloaded on witch route, else what you need to do it in your controller. - the containers will be reloaded after the controller has been executed, - but if you change or set a varible in your controller methode you will need to call wrapper.reloadAllContainers(options) - to propagate the changes to your containers. -

- -

- If you don't set the TagCommanderProvider.trackRoutes(true); (or you set it to false) you will have to reload your container manually -

-
-        {'// reload a specifique container'}
- wrapper.reloadContainer(ids, idc, options);
-
- {'// or you can reload all the containers'}
- wrapper.reloadAllContainers(options);
-
- -

How to set your Vars

-

In a component

-

- The setVar call allows to set your tc_vars. -

-
-      wrapper.setTcVars({'{'}
-     env_template : "shop",
-     env_work : "dev",
-     env_language : "en",
-     user_id : "124",
-     user_logged : "true",
-     user_age: "32",
-     user_newcustomer : "false"
- {'}'});
-
- {'// you can also override some varible'}
- if (isNewUser) {'{'}
-     wrapper.setTcVars({'{'}
-         user_newcustomer : "true"
- {'}'});
-
- {'// or set/update them individualy'}
- wrapper.setTcVar('env_template', 'super_shop');
-
- {'// you can also remove a var'}
- wrapper.removeTcVars('env_template');
-
- -

In render function(JSX)

-

- You can set your tc_vars with the TcVars Component -

-
-        <TcVars env_language="fr" env_template="super_shop" />
-      
-
- ); - } +
+
+
+ ); +} export default Home; diff --git a/tag-commander-sample-app/src/components/shop/PageItem.jsx b/tag-commander-sample-app/src/components/shop/PageItem.jsx index 8ebc472..5b02209 100644 --- a/tag-commander-sample-app/src/components/shop/PageItem.jsx +++ b/tag-commander-sample-app/src/components/shop/PageItem.jsx @@ -3,7 +3,7 @@ import logo from '../../assets/Tag-Commander.png'; // Tell webpack this JS file function PageItem({ addToItems, defaultStoreCurrency }) { const [item, setItem] = useState({ - name: "Month Subscription", + name: "Shop Item 1", price: 99, quantity: 1 }); diff --git a/tag-commander-sample-app/src/components/shop/index.jsx b/tag-commander-sample-app/src/components/shop/index.jsx index d1eb6b2..958c590 100644 --- a/tag-commander-sample-app/src/components/shop/index.jsx +++ b/tag-commander-sample-app/src/components/shop/index.jsx @@ -13,7 +13,7 @@ const Shop = () => { ]}) }, []); - const [items, setItems] = useState([{ id: 0, name: "TagCommander", price: 20, quantity: 1 }]); + const [items, setItems] = useState([{ id: 0, name: "Shop Item 2", price: 20, quantity: 1 }]); const defaultStoreCurrency = "€"; const [isMsgDisplayed, setIsMsgDisplayed] = useState(false); const [currentId, setCurrentId] = useState(1);