├── .commitlintrc.json
├── .eslintrc.js
├── .github
└── workflows
│ └── deploy.yml
├── .gitignore
├── .lintstagedrc
├── .markdownlint.json
├── .prettierignore
├── .prettierrc
├── LICENSE
├── README.md
├── content
├── code-examples
│ ├── changes
│ │ ├── applyMany.md
│ │ ├── applyOne.md
│ │ ├── get.md
│ │ └── getCount.md
│ ├── environments
│ │ ├── create-environment.md
│ │ ├── get-all-environments.md
│ │ ├── get-api-keys.md
│ │ ├── get-current-environment.md
│ │ ├── regenerate-api-keys.md
│ │ ├── update-environment.md
│ │ └── update-widget.md
│ ├── events
│ │ ├── broadcast.md
│ │ ├── cancel.md
│ │ └── trigger.md
│ ├── feeds
│ │ ├── create.md
│ │ ├── delete.md
│ │ └── get.md
│ ├── integrations
│ │ ├── create.md
│ │ ├── delete.md
│ │ ├── getActive.md
│ │ ├── getAll.md
│ │ ├── getWebhookProviderStatus.md
│ │ └── update.md
│ ├── notification-groups
│ │ ├── create.md
│ │ ├── delete.md
│ │ ├── get-one.md
│ │ ├── get.md
│ │ └── update.md
│ ├── notification-templates
│ │ ├── create.md
│ │ ├── delete.md
│ │ ├── get-all.md
│ │ ├── get-one.md
│ │ ├── update-status.md
│ │ └── update.md
│ └── subscribers
│ │ ├── delete.md
│ │ ├── get-notifications-feed.md
│ │ ├── get-preference.md
│ │ ├── get-unseen-count.md
│ │ ├── get.md
│ │ ├── identity.md
│ │ ├── list.md
│ │ ├── mark-message-action-seen.md
│ │ ├── mark-message-seen.md
│ │ ├── set-credentials.md
│ │ ├── update-preference.md
│ │ └── update.md
└── pages
│ └── api-reference
│ ├── api-authorization
│ └── api-authorization.md
│ ├── client-libraries
│ └── client-libraries.md
│ └── overview
│ └── overview.md
├── gatsby-browser.js
├── gatsby-config.js
├── gatsby-node.js
├── gatsby-ssr.js
├── jsconfig.json
├── netlify.toml
├── package-lock.json
├── package.json
├── pnpm-lock.yaml
├── postcss.config.js
├── src
├── components
│ ├── pages
│ │ ├── api-reference
│ │ │ └── overview
│ │ │ │ ├── index.js
│ │ │ │ └── overview.jsx
│ │ └── main
│ │ │ └── sections
│ │ │ ├── index.js
│ │ │ └── sections.jsx
│ └── shared
│ │ ├── burger
│ │ ├── burger.jsx
│ │ └── index.js
│ │ ├── code-snippets
│ │ ├── code-snippets.jsx
│ │ ├── code
│ │ │ ├── code.jsx
│ │ │ └── index.js
│ │ └── index.js
│ │ ├── code
│ │ ├── code.jsx
│ │ └── index.js
│ │ ├── footer
│ │ ├── footer.jsx
│ │ └── index.js
│ │ ├── header
│ │ ├── header.jsx
│ │ ├── index.js
│ │ └── theme-switcher
│ │ │ ├── images
│ │ │ ├── moon.inline.svg
│ │ │ └── sun.inline.svg
│ │ │ ├── index.js
│ │ │ └── theme-switcher.jsx
│ │ ├── layout
│ │ ├── index.js
│ │ └── layout.jsx
│ │ ├── link
│ │ ├── index.js
│ │ └── link.jsx
│ │ ├── method-with-endpoint
│ │ ├── index.js
│ │ └── method-with-endpoint.jsx
│ │ ├── mobile-menu
│ │ ├── index.js
│ │ └── mobile-menu.jsx
│ │ ├── navigation
│ │ ├── index.js
│ │ └── navigation.jsx
│ │ ├── parametr-with-type
│ │ ├── index.js
│ │ ├── parametr-with-type.jsx
│ │ └── sub-parametr
│ │ │ ├── index.js
│ │ │ ├── sub-parametr.jsx
│ │ │ └── sub-sub-parametr
│ │ │ ├── index.js
│ │ │ └── sub-sub-parametr.jsx
│ │ ├── response-code
│ │ ├── index.js
│ │ └── response-code.jsx
│ │ ├── section-with-content
│ │ ├── index.js
│ │ └── section-with-content.jsx
│ │ ├── section-wrapper
│ │ ├── index.js
│ │ └── section-wrapper.jsx
│ │ └── seo
│ │ ├── index.js
│ │ └── seo.jsx
├── config
│ └── index.js
├── constants
│ ├── links.js
│ └── menus.js
├── hooks
│ └── .gitkeep
├── html.jsx
├── icons
│ ├── arrow.inline.svg
│ ├── copy.inline.svg
│ ├── github.inline.svg
│ └── plus.inline.svg
├── images
│ ├── algolia-black-logo.svg
│ ├── algolia-white-logo.svg
│ ├── favicon.png
│ └── logo.inline.svg
├── pages
│ └── .gitkeep
├── styles
│ ├── code-highlighting.css
│ ├── container.css
│ ├── content.css
│ ├── fonts.css
│ ├── global.css
│ ├── main.css
│ ├── remove-search-cancel-button.css
│ ├── safe-paddings.css
│ ├── scrollbar-hidden.css
│ └── search.css
├── templates
│ ├── 404.jsx
│ └── main.jsx
└── utils
│ ├── generate-responses.jsx
│ ├── generate-snippets.jsx
│ ├── get-all-data.js
│ ├── get-path-without-prefix.js
│ ├── get-value-for-parameter.js
│ └── scroll-to-section.js
├── static
├── fonts
│ ├── brother-1816
│ │ ├── brother-1816-book.woff2
│ │ ├── brother-1816-medium.woff2
│ │ └── brother-1816-regular.woff2
│ └── ibm-plex-mono
│ │ ├── ibm-plex-mono-regular.woff2
│ │ └── ibm-plex-mono-semibold.woff2
└── images
│ └── social-preview.jpg
└── tailwind.config.js
/.commitlintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["@commitlint/config-conventional"],
3 | "rules": {
4 | "scope-enum": [
5 | 2,
6 | "always",
7 | [
8 | "components",
9 | "constants",
10 | "hooks",
11 | "icons",
12 | "images",
13 | "pages",
14 | "styles",
15 | "templates",
16 | "utils"
17 | ]
18 | ]
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | browser: true,
4 | es6: true,
5 | },
6 | extends: ['airbnb', 'airbnb/hooks', 'airbnb/whitespace', 'prettier'],
7 | globals: {
8 | Atomics: 'readonly',
9 | SharedArrayBuffer: 'readonly',
10 | },
11 | parserOptions: {
12 | ecmaFeatures: {
13 | jsx: true,
14 | },
15 | ecmaVersion: 2020,
16 | sourceType: 'module',
17 | },
18 | plugins: ['react'],
19 | rules: {
20 | // Removes "default" from "restrictedNamedExports", original rule setup — https://github.com/airbnb/javascript/blob/master/packages/eslint-config-airbnb-base/rules/es6.js#L65
21 | 'no-restricted-exports': ['error', { restrictedNamedExports: ['then'] }],
22 | 'no-unused-vars': 'error',
23 | 'no-shadow': 'off',
24 | 'no-undef': 'error',
25 | 'react/prop-types': 'error',
26 | 'react/no-array-index-key': 'off',
27 | 'react/jsx-props-no-spreading': 'off',
28 | 'react/no-danger': 'off',
29 | 'react/forbid-prop-types': 'off',
30 | // Changes values from "function-expression" to "arrow-function", original rule setup — https://github.com/airbnb/javascript/blob/master/packages/eslint-config-airbnb/rules/react.js#L528
31 | 'react/function-component-definition': [
32 | 'error',
33 | {
34 | namedComponents: 'arrow-function',
35 | unnamedComponents: 'arrow-function',
36 | },
37 | ],
38 | 'react/jsx-sort-props': [
39 | 'error',
40 | {
41 | callbacksLast: true,
42 | shorthandLast: true,
43 | noSortAlphabetically: true,
44 | },
45 | ],
46 | 'import/order': [
47 | 'error',
48 | {
49 | groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'object'],
50 | 'newlines-between': 'always',
51 | alphabetize: {
52 | order: 'asc',
53 | caseInsensitive: true,
54 | },
55 | },
56 | ],
57 | 'import/no-extraneous-dependencies': [
58 | 'error',
59 | {
60 | devDependencies: [
61 | '.storybook/**',
62 | 'src/components/**/*.stories.js',
63 | 'src/components/**/*.stories.jsx',
64 | 'gatsby-config.js',
65 | 'gatsby-node.js',
66 | 'gatsby-ssr.js',
67 | ],
68 | },
69 | ],
70 | 'jsx-a11y/label-has-associated-control': [
71 | 'error',
72 | {
73 | required: {
74 | some: ['nesting', 'id'],
75 | },
76 | },
77 | ],
78 | 'jsx-a11y/label-has-for': [
79 | 'error',
80 | {
81 | required: {
82 | some: ['nesting', 'id'],
83 | },
84 | },
85 | ],
86 | },
87 | settings: {
88 | 'import/resolver': {
89 | node: {
90 | paths: ['src'],
91 | },
92 | },
93 | },
94 | };
95 |
--------------------------------------------------------------------------------
/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | name: Deploy
2 |
3 | on:
4 | # Allows you to run this workflow manually from the Actions tab
5 | workflow_dispatch:
6 |
7 | jobs:
8 | deployment:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: Deploy Stage
12 | uses: fjogeleit/http-request-action@v1
13 | with:
14 | url: ${{ secrets.BUILD_WEBHOOK }}
15 | method: 'POST'
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 |
9 | # Diagnostic reports (https://nodejs.org/api/report.html)
10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11 |
12 | # Runtime data
13 | pids
14 | *.pid
15 | *.seed
16 | *.pid.lock
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 | *.lcov
24 |
25 | # nyc test coverage
26 | .nyc_output
27 |
28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29 | .grunt
30 |
31 | # Bower dependency directory (https://bower.io/)
32 | bower_components
33 |
34 | # node-waf configuration
35 | .lock-wscript
36 |
37 | # Compiled binary addons (https://nodejs.org/api/addons.html)
38 | build/Release
39 |
40 | # Dependency directories
41 | node_modules/
42 | jspm_packages/
43 |
44 | # TypeScript v1 declaration files
45 | typings/
46 |
47 | # TypeScript cache
48 | *.tsbuildinfo
49 |
50 | # Optional npm cache directory
51 | .npm
52 |
53 | # Optional eslint cache
54 | .eslintcache
55 |
56 | # Optional eslint cache
57 | .stylelintcache
58 |
59 | # Optional REPL history
60 | .node_repl_history
61 |
62 | # Output of 'npm pack'
63 | *.tgz
64 |
65 | # dotenv environment variable files
66 | .env*
67 | !.env.example
68 |
69 | # gatsby files
70 | .cache/
71 | public
72 |
73 | # Mac files
74 | .DS_Store
75 |
76 | # Yarn
77 | yarn-error.log
78 | .pnp/
79 | .pnp.js
80 | yarn.lock
81 | # Yarn Integrity file
82 | .yarn-integrity
83 |
84 | .vscode/snipsnap.code-snippets
85 |
--------------------------------------------------------------------------------
/.lintstagedrc:
--------------------------------------------------------------------------------
1 | {
2 | "*.{js,jsx,html,css,md}": "prettier --write",
3 | "*.{js,jsx}": "eslint --cache --fix",
4 | "*.md": "markdownlint --fix"
5 | }
6 |
--------------------------------------------------------------------------------
/.markdownlint.json:
--------------------------------------------------------------------------------
1 | {
2 | "line-length": false,
3 | "ol-prefix": false
4 | }
5 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | .cache
2 | package.json
3 | package-lock.json
4 | public
5 | content
6 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 100,
3 | "tabWidth": 2,
4 | "useTabs": false,
5 | "semi": true,
6 | "singleQuote": true,
7 | "quoteProps": "as-needed",
8 | "jsxSingleQuote": false,
9 | "trailingComma": "es5",
10 | "bracketSpacing": true,
11 | "jsxBracketSameLine": false,
12 | "arrowParens": "always",
13 | "endOfLine": "lf"
14 | }
15 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2022, Novu
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | 1. Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | 3. Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 | Notification management simplified.
14 |
15 |
16 |
17 | The ultimate service for managing multi-channel notifications with a single API.
18 |
19 |
20 |
21 |
22 | Explore the docs »
23 |
24 |
25 |
26 | Report Bug
27 | ·
28 | Request Feature
29 | ·
30 | Join Our Discord
31 | ·
32 | Roadmap
33 | ·
34 | Twitter
35 |
36 |
37 | ## API Documentation
38 |
39 | This repository is the tool used to generate the API documentation using [Gatsby](https://www.gatsbyjs.com/) static sites generator.
40 | The content is retrieved from Novu's API Swagger set in the [API app](https://github.com/novuhq/novu/blob/1c40d2b5ff39ae9d5e0ab9714f2600061e25028e/apps/api/src/bootstrap.ts#L95), parsed and generated by Gatsby.
41 |
42 | ## 🚀 Getting Started
43 |
44 | ### Local development
45 |
46 | In order to run the API documentation generator locally you will need [NPM](https://www.npmjs.com/) installed in your local environment.
47 |
48 | Then you firstly will install the project.
49 | ```sh
50 | npm install
51 | ```
52 |
53 | And then to run it.
54 | ```sh
55 | npm start
56 | ```
57 |
58 | Behind the scenes, the `start` script what it does is to call the `develop` script that runs Gatsby locally, executing the fetching of all the data, its parsing and generating the static content with the documentation for Novu's API.
59 |
60 | For development purposes is recommended to set this environment variable located in `./.env` (generated by copying `./.env.example`.
61 | ```sh
62 | GATSBY_NOVU_API_URL=http://localhost:3000
63 | NOVU_API_URL=http://localhost:3000
64 | ```
65 | You would need to set the value of the URL where your local development Novu API is being deployed. By default configuration Novu API is set to `http://localhost:3000` but be aware that changing the default port values or where it is deployed will have a knock on effect for the API documentation generator here.
66 | `GATSBY_NOVU_API_URL` will render the proper URL in the content generated by Gatsby, allowing to quickly copy and paste the code examples generated for development use.
67 |
68 |
69 | ### How it works?
70 |
71 | Basically we [fetch](https://github.com/novuhq/api-docs/blob/756f34e8ebfa464973bf4a8b31640b39ed150dd0/src/utils/get-all-data.js#L11) all the information from the Swagger endpoint of Novu API `/api-json` and that data is being parsed.
72 | There are two key things for the Swagger data to be able to be parsed. One is to define the [`tags`](https://github.com/novuhq/novu/blob/1c40d2b5ff39ae9d5e0ab9714f2600061e25028e/apps/api/src/bootstrap.ts#L81) for the different API resources. Second one is to add to the different public API endpoints that are going to be documented, the property `summary` with a short description of what the endpoint is for.
73 | Once the content is parsed and based on how it is defined in Swagger, Gatsby will generate the static content with the API endpoint definitions provided and some examples.
74 |
--------------------------------------------------------------------------------
/content/code-examples/changes/applyMany.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu apply several changes
3 | id: post-/v1/changes/bulk/apply
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.changes.applyMany({[changeIds]});
13 | ```
14 |
--------------------------------------------------------------------------------
/content/code-examples/changes/applyOne.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu apply one change
3 | id: post-/v1/changes/:changeId/apply
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.changes.applyOne(changeId);
13 | ```
14 |
--------------------------------------------------------------------------------
/content/code-examples/changes/get.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu get all changes
3 | id: get-/v1/changes
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.changes.get();
13 | ```
14 |
--------------------------------------------------------------------------------
/content/code-examples/changes/getCount.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu get the count of all changes
3 | id: get-/v1/changes/count
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.changes.getCount();
13 | ```
14 |
--------------------------------------------------------------------------------
/content/code-examples/environments/create-environment.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu create one environment
3 | id: post-/v1/environments/
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | const payload: IEnvironmentCreatePayload = {
13 | name: 'test',
14 | parentId: 'as20dfbjsfi3ssdk39dh'
15 | }
16 |
17 | await novu.environments.create(payload);
18 | ```
19 |
--------------------------------------------------------------------------------
/content/code-examples/environments/get-all-environments.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu get all environments
3 | id: get-/v1/environments/
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.environments.getAll();
13 | ```
14 |
--------------------------------------------------------------------------------
/content/code-examples/environments/get-api-keys.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu get all api keys
3 | id: get-/v1/environments/api-keys
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.environments.getApiKeys();
13 | ```
14 |
--------------------------------------------------------------------------------
/content/code-examples/environments/get-current-environment.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu get current environment
3 | id: get-/v1/environments/me
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.environments.getCurrent();
13 | ```
14 |
--------------------------------------------------------------------------------
/content/code-examples/environments/regenerate-api-keys.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu regenerate api keys
3 | id: post-/v1/environments/api-keys/regenerate
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.environments.regenerateApiKeys();
13 | ```
14 |
--------------------------------------------------------------------------------
/content/code-examples/environments/update-environment.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu update one environment
3 | id: put-/v1/environments/:environmentId
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | const payload: IEnvironmentUpdatePayload = {
13 | name: 'new environment';
14 | identifier: 'test env';
15 | parentId: '109ufdsnfkhk890hhjsdf';
16 | }
17 |
18 | const envId = '12390dsfkhjk9dfd'
19 |
20 | await novu.environments.updateOne(envId, payload);
21 | ```
22 |
--------------------------------------------------------------------------------
/content/code-examples/environments/update-widget.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu update widget settings
3 | id: put-/v1/environments/widget/settings
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | const payload: IWidgetUpdatePayload = {
13 | notificationCenterEncryption: true
14 | }
15 |
16 | await novu.environments.updateWidget(payload);
17 | ```
18 |
--------------------------------------------------------------------------------
/content/code-examples/events/broadcast.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu broadcast event
3 | id: post-/v1/events/trigger/broadcast
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.broadcast('',
13 | {
14 | payload: {
15 | customVariables: 'Hello'
16 | },
17 | transactionId: 'transactionId',
18 | }
19 | );
20 | ```
21 |
22 | ```bash label=cURL
23 | curl -X POST \
24 | -H "Content-Type: application/json" \
25 | -H "Authorization: ApiKey REPLACE_WITH_API_KEY" \
26 | -d '{
27 | "name": "Novu",
28 | "payload": {
29 | "test": "test"
30 | },
31 | "transactionId": "transactionId"
32 | }' \
33 | https://api.novu.co/v1/events/trigger/brodcast
34 | ```
35 |
--------------------------------------------------------------------------------
/content/code-examples/events/cancel.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu Cancel event
3 | id: delete-/v1/events/trigger/:transactionId
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.events.cancel('transactionId');
13 | ```
14 |
15 | ```bash label=cURL
16 | curl -X DELETE \
17 | -H "Content-Type: application/json" \
18 | -H "Authorization: ApiKey REPLACE_WITH_API_KEY" \
19 | https://api.novu.co/v1/events/trigger/transactionId
20 | ```
21 |
--------------------------------------------------------------------------------
/content/code-examples/events/trigger.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu Trigger event
3 | id: post-/v1/events/trigger
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.trigger('',
13 | {
14 | to: {
15 | subscriberId: '',
16 | email: 'email@email.com',
17 | firstName: 'John',
18 | lastName: 'Doe',
19 | },
20 | payload: {
21 | customVariables: 'Hello'
22 | },
23 | transactionId: 'transactionId',
24 | }
25 | );
26 | ```
27 |
28 | ```bash label=cURL
29 | curl -X POST \
30 | -H "Content-Type: application/json" \
31 | -H "Authorization: ApiKey REPLACE_WITH_API_KEY" \
32 | -d '{
33 | "name": "Novu",
34 | "payload": {
35 | "test": "test"
36 | },
37 | "to": "to",
38 | "transactionId": "transactionId"
39 | }' \
40 | https://api.novu.co/v1/events/trigger
41 | ```
42 |
--------------------------------------------------------------------------------
/content/code-examples/feeds/create.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu create feeds template
3 | id: post-/v1/feeds/:name
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.feeds.create({
13 | name: "name"
14 | });
15 | ```
16 | ```bash label=cURL
17 | curl -X POST \
18 | -H "Authorization: ApiKey REPLACE_WITH_API_KEY" \
19 | -H "Content-Type: application/json" \
20 | -d '{
21 | "name": "name"
22 | }' \
23 | https://api.novu.co/v1/feeds
24 | ```
--------------------------------------------------------------------------------
/content/code-examples/feeds/delete.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu Delete feed template
3 | id: delete-/v1/feeds/delete/:feedId
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.feeds.delete('feedId');
13 | ```
14 |
15 | ```bash label=cURL
16 | curl -X DELETE \
17 | -H "Content-Type: application/json" \
18 | -H "Authorization: ApiKey REPLACE_WITH_API_KEY" \
19 | https://api.novu.co/v1/feeds/delete/feedId
20 | ```
21 |
--------------------------------------------------------------------------------
/content/code-examples/feeds/get.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu get feeds
3 | id: get-/v1/feeds/
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.feeds.get();
13 | ```
14 | ```bash label=cURL
15 | curl -X GET \
16 | -H "Content-Type: application/json" \
17 | -H "Authorization: ApiKey REPLACE_WITH_API_KEY" \
18 | https://api.novu.co/v1/feeds
19 | ```
--------------------------------------------------------------------------------
/content/code-examples/integrations/create.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu create an integration
3 | id: post-/v1/integrations
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 | export const novu = new Novu('');
10 | await novu.integrations.create('providerId', {
11 | credentials: credentials,
12 | active: true,
13 | channel: "channel",
14 | check: true
15 | });
16 | ```
--------------------------------------------------------------------------------
/content/code-examples/integrations/delete.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu Delete an integration
3 | id: delete-/v1/integrations/:integrationId
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 | export const novu = new Novu('');
10 | await novu.integrations.delete('integrationId');
11 | ```
--------------------------------------------------------------------------------
/content/code-examples/integrations/getActive.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu Get all active integrations
3 | id: get-/v1/integrations/active
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 | export const novu = new Novu('');
10 | await novu.integrations.getActive();
11 | ```
--------------------------------------------------------------------------------
/content/code-examples/integrations/getAll.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu Get all connected integrations
3 | id: get-/v1/integrations
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 | export const novu = new Novu('');
10 | await novu.integrations.getAll();
11 | ```
--------------------------------------------------------------------------------
/content/code-examples/integrations/getWebhookProviderStatus.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu Get the webhook provider status of the integration provider
3 | id: get-/v1/integrations/webhook/provider/:providerId/status
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 | export const novu = new Novu('');
10 | await novu.integrations.getWebhookProviderStatus();
11 | ```
--------------------------------------------------------------------------------
/content/code-examples/integrations/update.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu Update an integration
3 | id: put-/v1/integrations/:integrationId
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 | export const novu = new Novu('');
10 | await novu.integrations.update('integrationId', {
11 | active: true,
12 | credentials: credentials,
13 | check: true
14 | });
15 | ```
--------------------------------------------------------------------------------
/content/code-examples/notification-groups/create.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu create notification group
3 | type: snippets
4 | ---
5 |
6 | ```javascript label=Node.js
7 | import { Novu } from '@novu/node';
8 |
9 | export const novu = new Novu('');
10 |
11 | await novu.notificationGroups.create({
12 | name: "name"
13 | });
14 | ```
15 |
--------------------------------------------------------------------------------
/content/code-examples/notification-groups/delete.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu delete notification group
3 | type: snippets
4 | ---
5 |
6 | ```javascript label=Node.js
7 | import { Novu } from '@novu/node';
8 |
9 | export const novu = new Novu('');
10 |
11 | await novu.notificationGroups.delete("groupId");
12 | ```
13 |
--------------------------------------------------------------------------------
/content/code-examples/notification-groups/get-one.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu get single notification group
3 | type: snippets
4 | ---
5 |
6 | ```javascript label=Node.js
7 | import { Novu } from '@novu/node';
8 |
9 | export const novu = new Novu('');
10 |
11 | await novu.notificationGroups.getOne("groupId");
12 | ```
13 |
--------------------------------------------------------------------------------
/content/code-examples/notification-groups/get.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu gets all the notification groups
3 | type: snippets
4 | ---
5 |
6 | ```javascript label=Node.js
7 | import { Novu } from '@novu/node';
8 |
9 | export const novu = new Novu('');
10 |
11 | await novu.notificationGroups.get();
12 | ```
13 |
--------------------------------------------------------------------------------
/content/code-examples/notification-groups/update.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu update notification group
3 | type: snippets
4 | ---
5 |
6 | ```javascript label=Node.js
7 | import { Novu } from '@novu/node';
8 |
9 | export const novu = new Novu('');
10 |
11 | await novu.notificationGroups.update("groupId", {
12 | name: "name"
13 | })
14 | ```
15 |
--------------------------------------------------------------------------------
/content/code-examples/notification-templates/create.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu create notification template
3 | type: snippets
4 | ---
5 |
6 | ```javascript label=Node.js
7 | import { Novu } from '@novu/node';
8 |
9 | export const novu = new Novu('');
10 |
11 | await novu.notificationTemplates.create({
12 | name: "name",
13 | notificationGroupId: "notificationGroupId",
14 | tags: ["tags"],
15 | description: "description",
16 | steps: ["steps"],
17 | active: true,
18 | draft: true,
19 | critical: true,
20 | preferenceSettings: preferenceSettings
21 | });
22 | ```
23 |
--------------------------------------------------------------------------------
/content/code-examples/notification-templates/delete.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu delete notification template
3 | type: snippets
4 | ---
5 |
6 | ```javascript label=Node.js
7 | import { Novu } from '@novu/node';
8 |
9 | export const novu = new Novu('');
10 |
11 | await novu.notificationTemplates.delete("templateId");
12 | ```
13 |
--------------------------------------------------------------------------------
/content/code-examples/notification-templates/get-all.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu gets all the notification-templates
3 | type: snippets
4 | ---
5 |
6 | ```javascript label=Node.js
7 | import { Novu } from '@novu/node';
8 |
9 | export const novu = new Novu('');
10 |
11 | await novu.notificationTemplates.getAll(1, 10);
12 | ```
13 |
--------------------------------------------------------------------------------
/content/code-examples/notification-templates/get-one.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu get single notification template
3 | type: snippets
4 | ---
5 |
6 | ```javascript label=Node.js
7 | import { Novu } from '@novu/node';
8 |
9 | export const novu = new Novu('');
10 |
11 | await novu.notificationTemplates.getOne("templateId");
12 | ```
13 |
--------------------------------------------------------------------------------
/content/code-examples/notification-templates/update-status.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu update status of notification template
3 | type: snippets
4 | ---
5 |
6 | ```javascript label=Node.js
7 | import { Novu } from '@novu/node';
8 |
9 | export const novu = new Novu('');
10 |
11 | await novu.notificationTemplates.updateStatus('templateId', true);
12 | ```
13 |
--------------------------------------------------------------------------------
/content/code-examples/notification-templates/update.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu update notification template
3 | type: snippets
4 | ---
5 |
6 | ```javascript label=Node.js
7 | import { Novu } from '@novu/node';
8 |
9 | export const novu = new Novu('');
10 |
11 | await novu.notificationTemplates.update("templateId", {
12 | name: "name",
13 | tags: ["tags"],
14 | description: "description",
15 | identifier: "identifier",
16 | steps: ["steps"],
17 | notificationGroupId: "notificationGroupId",
18 | active: true,
19 | critical: true,
20 | preferenceSettings: preferenceSettings
21 | })
22 | ```
23 |
--------------------------------------------------------------------------------
/content/code-examples/subscribers/delete.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu delete subscriber
3 | id: delete-/v1/subscribers/:subscriberId
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.subscribers.delete(user.id);
13 | ```
14 |
--------------------------------------------------------------------------------
/content/code-examples/subscribers/get-notifications-feed.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu get notifications feed
3 | id: get-/v1/subscribers/:subscriberId/notifications/feed
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.subscribers.getNotificationsFeed(user.id, {
13 | page: 0,
14 | seen: false,
15 | feedIdentifier
16 | });
17 | ```
18 |
--------------------------------------------------------------------------------
/content/code-examples/subscribers/get-preference.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu get subscriber preferences
3 | id: get-/v1/subscribers/:subscriberId/preferences
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.subscribers.getPreference(user.id);
13 | ```
14 |
--------------------------------------------------------------------------------
/content/code-examples/subscribers/get-unseen-count.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu get unseen count
3 | id: get-/v1/subscribers/:subscriberId/notifications/unseen
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.subscribers.getUnseenCount(user.id, false);
13 | ```
14 |
--------------------------------------------------------------------------------
/content/code-examples/subscribers/get.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu get subscriber
3 | id: get-/v1/subscribers/:subscriberId
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.subscribers.get(user.id);
13 | ```
14 |
--------------------------------------------------------------------------------
/content/code-examples/subscribers/identity.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu create subscriber
3 | id: post-/v1/subscribers
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.subscribers.identify(user.id, {
13 | email: user.email,
14 | firstName: user.firstName,
15 | lastName: user.lastName,
16 | phone: user.phone,
17 | avatar: user.profile_avatar
18 | });
19 | ```
20 |
--------------------------------------------------------------------------------
/content/code-examples/subscribers/list.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu get subscribers
3 | id: get-/v1/subscribers
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.subscribers.list(0);
13 | ```
14 |
--------------------------------------------------------------------------------
/content/code-examples/subscribers/mark-message-action-seen.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu mark message action seen
3 | id: post-/v1/subscribers/:subscriberId/messages/:messageId/actions/:type
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.subscribers.markMessageActionSeen(user.id, messageId, type);
13 | ```
14 |
--------------------------------------------------------------------------------
/content/code-examples/subscribers/mark-message-seen.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu mark message seen
3 | id: post-/v1/subscribers/:subscriberId/messages/:messageId/seen
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.subscribers.markMessageSeen(user.id, messageId);
13 | ```
14 |
--------------------------------------------------------------------------------
/content/code-examples/subscribers/set-credentials.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu subscriber set credentials
3 | id: put-/v1/subscribers/:subscriberId/credentials
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.subscribers.setCredentials(user.id, providerId, {
13 | webhookUrl: 'http://webhook.url/novu';
14 | notificationIdentifiers: [user.notificationIdentifier]
15 | });
16 | ```
17 |
--------------------------------------------------------------------------------
/content/code-examples/subscribers/update-preference.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu get subscriber preferences
3 | id: post-/v1/subscribers/:subscriberId/preferences/:templateId
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.subscribers.updatePreference(user.id, templateId, {
13 | channel: {
14 | type: 'fcm',
15 | enabled: true,
16 | },
17 | enabled: true,
18 | });
19 | ```
20 |
--------------------------------------------------------------------------------
/content/code-examples/subscribers/update.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Novu update subscriber
3 | id: put-/v1/subscribers/:subscriberId
4 | type: snippets
5 | ---
6 |
7 | ```javascript label=Node.js
8 | import { Novu } from '@novu/node';
9 |
10 | export const novu = new Novu('');
11 |
12 | await novu.subscribers.identify(user.id, {
13 | email: user.email,
14 | firstName: user.firstName,
15 | lastName: user.lastName,
16 | phone: user.phone,
17 | avatar: user.profile_avatar
18 | });
19 | ```
20 |
--------------------------------------------------------------------------------
/content/pages/api-reference/api-authorization/api-authorization.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: API Authorization
3 | slug: api-authorization
4 | sort: 2
5 | ---
6 |
7 | Novu API is authorized by passing the ApiKey (generated from the [settings page](https://web.novu.co/settings)) with each request.
8 |
9 | ### Header Format
10 | ```
11 | 'Authorization': 'ApiKey REPLACE_WITH_API_KEY'
12 | ```
13 |
--------------------------------------------------------------------------------
/content/pages/api-reference/client-libraries/client-libraries.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Client libraries
3 | slug: client-libraries
4 | sort: 3
5 | ---
6 |
7 | Novu offers native SDK in several popular programming languages:
8 |
9 | - [Go](https://github.com/novuhq/go-novu)
10 | - [Node.js](https://github.com/novuhq/novu/tree/main/packages/node)
11 | - [PHP](https://github.com/novuhq/novu-php)
12 | - [Ruby](https://github.com/novuhq/novu-ruby)
13 | - [Kotlin](https://github.com/novuhq/novu-kotlin)
14 | - [Python](https://github.com/novuhq/novu-python)
15 | - [.Net](https://github.com/novuhq/novu-dotnet)
16 |
--------------------------------------------------------------------------------
/content/pages/api-reference/overview/overview.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Overview
3 | slug: overview
4 | baseUrl: https://api.novu.co/v1
5 | sort: 1
6 | ---
7 |
8 | The API enables you to access the entire Novu platform using a RESTful API. This API provides a programmatic access to the platform's data and functionality.
--------------------------------------------------------------------------------
/gatsby-browser.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Implement Gatsby's Browser APIs in this file.
3 | *
4 | * See: https://www.gatsbyjs.org/docs/browser-apis/
5 | */
6 |
7 | import getPathWithoutPrefix from 'utils/get-path-without-prefix';
8 | import scrollToSection from 'utils/scroll-to-section';
9 | import './src/styles/main.css';
10 |
11 | export const onRouteUpdate = () => {
12 | if (process.env.NODE_ENV === 'production' && typeof window.plausible !== 'undefined') {
13 | window.plausible('pageview');
14 | }
15 | };
16 |
17 | export const onClientEntry = () => {
18 | const id = getPathWithoutPrefix(window.location.pathname);
19 | scrollToSection(id);
20 | };
21 |
--------------------------------------------------------------------------------
/gatsby-config.js:
--------------------------------------------------------------------------------
1 | // Gatsby has dotenv by default
2 | // eslint-disable-next-line import/no-extraneous-dependencies
3 | require('dotenv').config();
4 |
5 | module.exports = {
6 | flags: { DEV_SSR: process.env.GATSBY_DEV_SSR || false },
7 | pathPrefix: '/api',
8 | assetPrefix: process.env.GATSBY_DEFAULT_SITE_URL,
9 | trailingSlash: 'always',
10 | siteMetadata: {
11 | siteTitle: 'Novu API Reference',
12 | siteDescription:
13 | 'Novu is an open-source notification infrastructure built for the engineering teams to help them build rich product notification experiences without constantly re-inventing the wheel.',
14 | siteImage: '/api/images/social-preview.jpg',
15 | siteLanguage: 'en',
16 | siteUrl: process.env.GATSBY_DEFAULT_SITE_URL || 'http://localhost:8000',
17 | authorName: 'Pixel Point',
18 | },
19 | plugins: [
20 | 'gatsby-plugin-react-helmet',
21 | {
22 | resolve: 'gatsby-source-filesystem',
23 | options: {
24 | name: 'images',
25 | path: `${__dirname}/src/images`,
26 | },
27 | },
28 | {
29 | resolve: 'gatsby-source-filesystem',
30 | options: {
31 | path: `${__dirname}/content`,
32 | },
33 | },
34 | 'gatsby-plugin-image',
35 | 'gatsby-transformer-sharp',
36 | 'gatsby-transformer-remark',
37 | {
38 | resolve: 'gatsby-plugin-sharp',
39 | options: {
40 | defaults: {
41 | quality: 85,
42 | placeholder: 'none',
43 | },
44 | },
45 | },
46 | {
47 | resolve: 'gatsby-plugin-manifest',
48 | options: {
49 | name: 'gatsby-starter-default',
50 | short_name: 'starter',
51 | start_url: '/',
52 | display: 'minimal-ui',
53 | icon: 'src/images/favicon.png',
54 | },
55 | },
56 | {
57 | resolve: 'gatsby-plugin-svgr-svgo',
58 | options: {
59 | inlineSvgOptions: [
60 | {
61 | test: /\.inline.svg$/,
62 | svgoConfig: {
63 | plugins: [
64 | {
65 | name: 'preset-default',
66 | params: {
67 | overrides: {
68 | removeViewBox: false,
69 | },
70 | },
71 | },
72 | 'prefixIds',
73 | 'removeDimensions',
74 | ],
75 | },
76 | },
77 | ],
78 | },
79 | },
80 | {
81 | resolve: 'gatsby-plugin-gatsby-cloud',
82 | options: {
83 | headers: {
84 | '/*': ['Access-Control-Allow-Origin: *'],
85 | '/api/fonts/*': ['Cache-Control: public, max-age=31536000, immutable'],
86 | },
87 | },
88 | },
89 | {
90 | resolve: 'gatsby-plugin-netlify',
91 | options: {
92 | headers: {
93 | '/*': ['Access-Control-Allow-Origin: *'],
94 | '/api/fonts/*': ['Cache-Control: public, max-age=31536000, immutable'],
95 | },
96 | },
97 | },
98 | 'gatsby-alias-imports',
99 | 'gatsby-plugin-postcss',
100 | {
101 | resolve: 'gatsby-plugin-sitemap',
102 | options: {
103 | resolveSiteUrl: () => 'https://docs.novu.co/',
104 | output: '/',
105 | },
106 | },
107 | {
108 | resolve: 'gatsby-plugin-canonical-urls',
109 | options: {
110 | siteUrl: 'https://docs.novu.co',
111 | },
112 | },
113 | ],
114 | };
115 |
--------------------------------------------------------------------------------
/gatsby-node.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | const getAllData = require('./src/utils/get-all-data');
4 |
5 | async function createPages({ graphql, actions, menu, pages }) {
6 | const { createPage } = actions;
7 |
8 | const {
9 | data: { customPages },
10 | } = await graphql(`
11 | {
12 | customPages: allMarkdownRemark(filter: { fileAbsolutePath: { regex: "/pages/" } }) {
13 | nodes {
14 | id
15 | frontmatter {
16 | title
17 | slug
18 | }
19 | }
20 | }
21 | }
22 | `);
23 |
24 | pages.forEach((page) => {
25 | page.methods.forEach((method) => {
26 | createPage({
27 | path: method.slug,
28 | component: path.resolve('./src/templates/main.jsx'),
29 | context: {
30 | id: method.id,
31 | menu,
32 | sections: pages,
33 | seo: {
34 | title: method.summary,
35 | description: method.description,
36 | slug: method.slug,
37 | },
38 | },
39 | });
40 | });
41 | });
42 |
43 | customPages.nodes.forEach(({ frontmatter: { title, slug } }) => {
44 | createPage({
45 | path: slug,
46 | component: path.resolve('./src/templates/main.jsx'),
47 | context: {
48 | id: slug,
49 | menu,
50 | sections: pages,
51 | seo: {
52 | title,
53 | slug,
54 | },
55 | },
56 | });
57 | });
58 | }
59 |
60 | async function createNotFoundPage({ actions, menu }) {
61 | const { createPage } = actions;
62 |
63 | createPage({
64 | path: '/404',
65 | component: path.resolve('./src/templates/404.jsx'),
66 | context: {
67 | menu,
68 | },
69 | });
70 | }
71 |
72 | exports.createPages = async (args) => {
73 | const { pages, menu, methods } = await getAllData();
74 |
75 | const params = {
76 | ...args,
77 | pages,
78 | menu,
79 | methods,
80 | };
81 |
82 | await createPages(params);
83 | await createNotFoundPage(params);
84 | };
85 |
--------------------------------------------------------------------------------
/gatsby-ssr.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const SITE_DOMAIN = 'docs.novu.co';
4 | const PLAUSIBLE_DOMAIN = 'plausible.io';
5 | const SCRIPT_URI = '/js/script.js';
6 |
7 | // eslint-disable-next-line import/prefer-default-export
8 | export const onRenderBody = ({ setHeadComponents, setPreBodyComponents, setHtmlAttributes }) => {
9 | if (process.env.NODE_ENV === 'production') {
10 | const scriptProps = {
11 | 'data-domain': SITE_DOMAIN,
12 | src: `https://${PLAUSIBLE_DOMAIN}${SCRIPT_URI}`,
13 | };
14 |
15 | setHeadComponents([
16 | // eslint-disable-next-line react/jsx-filename-extension
17 | ,
18 | ,
19 | // See: https://plausible.io/docs/custom-event-goals#1-trigger-custom-events-with-javascript-on-your-site
20 | ,
28 | ]);
29 | }
30 |
31 | setPreBodyComponents([
32 |