├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ └── bug_report.md
└── workflows
│ └── npmpublish.yml
├── .gitignore
├── .prettierignore
├── .prettierrc
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── gatsby-node.js
├── index.js
├── package.json
└── yarn.lock
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: luanbitar
2 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/workflows/npmpublish.yml:
--------------------------------------------------------------------------------
1 | name: NPM publish
2 | on:
3 | release:
4 | types: [created]
5 |
6 | jobs:
7 | publish-npm:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/checkout@v2
11 | - uses: actions/setup-node@v1
12 | with:
13 | node-version: 12
14 | registry-url: https://registry.npmjs.org/
15 | - run: npm publish
16 | env:
17 | NODE_AUTH_TOKEN: ${{secrets.npm_token}}
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | farm.js
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | README.md
2 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": false,
3 | "singleQuote": false,
4 | "tabWidth": 2,
5 | "useTabs": false
6 | }
7 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at 7@lbitar.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Creative Commons Legal Code
2 |
3 | CC0 1.0 Universal
4 |
5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
12 | HEREUNDER.
13 |
14 | Statement of Purpose
15 |
16 | The laws of most jurisdictions throughout the world automatically confer
17 | exclusive Copyright and Related Rights (defined below) upon the creator
18 | and subsequent owner(s) (each and all, an "owner") of an original work of
19 | authorship and/or a database (each, a "Work").
20 |
21 | Certain owners wish to permanently relinquish those rights to a Work for
22 | the purpose of contributing to a commons of creative, cultural and
23 | scientific works ("Commons") that the public can reliably and without fear
24 | of later claims of infringement build upon, modify, incorporate in other
25 | works, reuse and redistribute as freely as possible in any form whatsoever
26 | and for any purposes, including without limitation commercial purposes.
27 | These owners may contribute to the Commons to promote the ideal of a free
28 | culture and the further production of creative, cultural and scientific
29 | works, or to gain reputation or greater distribution for their Work in
30 | part through the use and efforts of others.
31 |
32 | For these and/or other purposes and motivations, and without any
33 | expectation of additional consideration or compensation, the person
34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she
35 | is an owner of Copyright and Related Rights in the Work, voluntarily
36 | elects to apply CC0 to the Work and publicly distribute the Work under its
37 | terms, with knowledge of his or her Copyright and Related Rights in the
38 | Work and the meaning and intended legal effect of CC0 on those rights.
39 |
40 | 1. Copyright and Related Rights. A Work made available under CC0 may be
41 | protected by copyright and related or neighboring rights ("Copyright and
42 | Related Rights"). Copyright and Related Rights include, but are not
43 | limited to, the following:
44 |
45 | i. the right to reproduce, adapt, distribute, perform, display,
46 | communicate, and translate a Work;
47 | ii. moral rights retained by the original author(s) and/or performer(s);
48 | iii. publicity and privacy rights pertaining to a person's image or
49 | likeness depicted in a Work;
50 | iv. rights protecting against unfair competition in regards to a Work,
51 | subject to the limitations in paragraph 4(a), below;
52 | v. rights protecting the extraction, dissemination, use and reuse of data
53 | in a Work;
54 | vi. database rights (such as those arising under Directive 96/9/EC of the
55 | European Parliament and of the Council of 11 March 1996 on the legal
56 | protection of databases, and under any national implementation
57 | thereof, including any amended or successor version of such
58 | directive); and
59 | vii. other similar, equivalent or corresponding rights throughout the
60 | world based on applicable law or treaty, and any national
61 | implementations thereof.
62 |
63 | 2. Waiver. To the greatest extent permitted by, but not in contravention
64 | of, applicable law, Affirmer hereby overtly, fully, permanently,
65 | irrevocably and unconditionally waives, abandons, and surrenders all of
66 | Affirmer's Copyright and Related Rights and associated claims and causes
67 | of action, whether now known or unknown (including existing as well as
68 | future claims and causes of action), in the Work (i) in all territories
69 | worldwide, (ii) for the maximum duration provided by applicable law or
70 | treaty (including future time extensions), (iii) in any current or future
71 | medium and for any number of copies, and (iv) for any purpose whatsoever,
72 | including without limitation commercial, advertising or promotional
73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
74 | member of the public at large and to the detriment of Affirmer's heirs and
75 | successors, fully intending that such Waiver shall not be subject to
76 | revocation, rescission, cancellation, termination, or any other legal or
77 | equitable action to disrupt the quiet enjoyment of the Work by the public
78 | as contemplated by Affirmer's express Statement of Purpose.
79 |
80 | 3. Public License Fallback. Should any part of the Waiver for any reason
81 | be judged legally invalid or ineffective under applicable law, then the
82 | Waiver shall be preserved to the maximum extent permitted taking into
83 | account Affirmer's express Statement of Purpose. In addition, to the
84 | extent the Waiver is so judged Affirmer hereby grants to each affected
85 | person a royalty-free, non transferable, non sublicensable, non exclusive,
86 | irrevocable and unconditional license to exercise Affirmer's Copyright and
87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the
88 | maximum duration provided by applicable law or treaty (including future
89 | time extensions), (iii) in any current or future medium and for any number
90 | of copies, and (iv) for any purpose whatsoever, including without
91 | limitation commercial, advertising or promotional purposes (the
92 | "License"). The License shall be deemed effective as of the date CC0 was
93 | applied by Affirmer to the Work. Should any part of the License for any
94 | reason be judged legally invalid or ineffective under applicable law, such
95 | partial invalidity or ineffectiveness shall not invalidate the remainder
96 | of the License, and in such case Affirmer hereby affirms that he or she
97 | will not (i) exercise any of his or her remaining Copyright and Related
98 | Rights in the Work or (ii) assert any associated claims and causes of
99 | action with respect to the Work, in either case contrary to Affirmer's
100 | express Statement of Purpose.
101 |
102 | 4. Limitations and Disclaimers.
103 |
104 | a. No trademark or patent rights held by Affirmer are waived, abandoned,
105 | surrendered, licensed or otherwise affected by this document.
106 | b. Affirmer offers the Work as-is and makes no representations or
107 | warranties of any kind concerning the Work, express, implied,
108 | statutory or otherwise, including without limitation warranties of
109 | title, merchantability, fitness for a particular purpose, non
110 | infringement, or the absence of latent or other defects, accuracy, or
111 | the present or absence of errors, whether or not discoverable, all to
112 | the greatest extent permissible under applicable law.
113 | c. Affirmer disclaims responsibility for clearing rights of other persons
114 | that may apply to the Work or any use thereof, including without
115 | limitation any person's Copyright and Related Rights in the Work.
116 | Further, Affirmer disclaims responsibility for obtaining any necessary
117 | consents, permissions or other rights required for any use of the
118 | Work.
119 | d. Affirmer understands and acknowledges that Creative Commons is not a
120 | party to this document and has no duty or obligation with respect to
121 | this CC0 or use of the Work.
122 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://www.npmjs.com/package/gatsby-plugin-dynamic-routes)
2 | [](https://www.npmjs.com/package/gatsby-plugin-dynamic-routes)
3 |
4 | # gatsby-plugin-dynamic-routes
5 |
6 | Use one file to declare your routes, provides to chose dynamic route paths based on your `BUILD_ENV` or `ROUTE_ENV` to your custom routing env. Also it's possible to only renaming routes on `pages/`, or use everything together.
7 |
8 | ## Install
9 |
10 | `$ npm i gatsby-plugin-dynamic-routes`
11 |
12 | or
13 |
14 | `$ yarn add gatsby-plugin-dynamic-routes`
15 |
16 | ## How to use
17 |
18 | Add the plugin to your `gatsby-config.js`.
19 |
20 | ```javascript
21 | module.exports = {
22 | plugins: [
23 | `gatsby-plugin-dynamic-routes`
24 | ]
25 | }
26 | ```
27 |
28 | Create your's `Routes.js` inside your `src/` folder
29 |
30 | ```bash
31 | project/
32 | ├── src/
33 | └── Routes.js
34 | ```
35 |
36 | `Routes.js`
37 |
38 | ```javascript
39 | module.exports = {
40 | home: {
41 | path: `/casa`,
42 | component: `src/pages/Home.js`
43 | }
44 | }
45 | ```
46 |
47 | Use in client-side, include globals comment
48 |
49 | `component/Example.js`
50 |
51 | ```javascript
52 | import { Link } from "gatsby"
53 |
54 | function Example() {
55 | return
56 | }
57 | ```
58 |
59 | ## Dynamic routes
60 |
61 | `Routes.js`
62 |
63 | ```javascript
64 | module.exports = {
65 | development: {
66 | two: {
67 | path: `/2`,
68 | component: `src/pages/Two.js`
69 | }
70 | },
71 | staging: {
72 | two: {
73 | path: `/dois`,
74 | component: `src/pages/Two.js`
75 | }
76 | },
77 | home: {
78 | path: `/casa`,
79 | component: `src/pages/Home.js`
80 | }
81 | }
82 | ```
83 |
84 | Run with your `BUILD_ENV` environment
85 |
86 | ```bash
87 | BUILD_ENV=staging yarn start
88 | ```
89 |
90 | If you are using the plugin [Dynamic Environment Variables][1], what will happen is that your environments inside your `.env` and `.env.staging` will be loaded, and your routes inside `staging` key will go to root of the object that is exported of `Routes` and will be available in yours global environment variables.
91 |
92 | `component/Example.js`
93 |
94 | ```javascript
95 | import { Link } from "gatsby"
96 | /* globals ROUTES */
97 |
98 | function Example() {
99 | return
100 | }
101 | ```
102 |
103 | Note that you need to put `eslint globals comment` in each file that will use `ROUTES` global variable.
104 |
105 | You need to create an empty `.eslintrc` in root of your folder to remove this comments.
106 |
107 | If you are using eslint in your project, just update this key to your config:
108 |
109 | ```javascript
110 | {
111 | "rules": {
112 | "no-undef": "off"
113 | }
114 | }
115 | ```
116 |
117 | You can pass more than `path` or `component` keys, these keys will be available in your component later
118 |
119 | ## Variations
120 |
121 | If you want to made variations of the same environment, but whit different routes, you can use `ROUTE_ENV` variable to chose your dynamic routes
122 |
123 | `example`
124 |
125 | ```bash
126 | ROUTE_ENV=organic BUILD_ENV=production yarn build
127 | ```
128 |
129 | ## Options
130 |
131 | ### `routeFilePath`
132 |
133 | This options allows you to specify what's the path to your file with your Routes object
134 |
135 | Example:
136 |
137 | ```javascript
138 | module.exports = {
139 | plugins: [
140 | {
141 | resolve: `gatsby-plugin-dynamic-routes`,
142 | options: {
143 | routeFilePath: `config/Routes.js`
144 | }
145 | }
146 | ]
147 | }
148 | ```
149 |
150 | ```bash
151 | project/
152 | ├── config/
153 | └── Routes.js
154 | ```
155 |
156 | If you want to put in root of your project, simply put the name of your file
157 |
158 | ## Ignoring gatsby default page creator
159 |
160 | By default, gatsby generates one route to each file inside `pages/` folder, to disable this feature, put in you `gatsby-config.js`:
161 |
162 | ```js
163 | {
164 | resolve: `gatsby-plugin-page-creator`,
165 | options: {
166 | path: `${__dirname}/src/pages`,
167 | ignore: {
168 | patterns: [`**/*`],
169 | },
170 | },
171 | },
172 | ```
173 |
174 | ## Recommended plugins
175 |
176 | Check out the [Dynamic Environment Variables][1] plugin that provides you to load different files based on your env variables
177 |
178 | [1]: https://github.com/luanbitar/gatsby-env-variables
179 |
--------------------------------------------------------------------------------
/gatsby-node.js:
--------------------------------------------------------------------------------
1 | const path = require("path")
2 |
3 | function getDynamicRoutes(routeFilePath = `src/Routes`) {
4 | const routesFile = require(path.resolve(routeFilePath))
5 |
6 | const routeKeys = Object.keys(routesFile)
7 | const staticRouteKeys = routeKeys.filter(route => {
8 | const childKeys = Object.keys(routesFile[route])
9 | return childKeys.includes("path")
10 | })
11 | const staticRoutes = staticRouteKeys.reduce(
12 | (acc, route) => ({
13 | ...acc,
14 | [route]: routesFile[route]
15 | }),
16 | {}
17 | )
18 |
19 | const { ROUTE_ENV, BUILD_ENV, NODE_ENV } = process.env
20 | const environment = ROUTE_ENV || BUILD_ENV || NODE_ENV || "development"
21 |
22 | const dynamicRoutes = routesFile[environment] || {}
23 | const routes = Object.assign({}, staticRoutes, dynamicRoutes)
24 |
25 | return {
26 | routes,
27 | environment
28 | }
29 | }
30 |
31 | exports.createPages = ({ actions, reporter }, { routeFilePath }) => {
32 | const { routes, environment } = getDynamicRoutes(routeFilePath)
33 | reporter.info(
34 | `Will use '${environment}' env and creating this route keys: ${Object.keys(
35 | routes
36 | )}`
37 | )
38 |
39 | const activity = reporter.activityTimer(`Dynamic routes created`)
40 | activity.start()
41 |
42 | const { createPage } = actions
43 | Object.keys(routes).map(routeKey => {
44 | const route = routes[routeKey]
45 | reporter.info(`Creating route: ${route.path}`)
46 | createPage({
47 | path: route.path,
48 | component: path.resolve(route.component),
49 | context: route.context ? route.context : {},
50 | })
51 | })
52 | activity.end()
53 | }
54 |
55 | exports.onCreateWebpackConfig = ({ actions, plugins }, { routeFilePath }) => {
56 | const { routes } = getDynamicRoutes(routeFilePath)
57 |
58 | const ROUTES = Object.keys(routes).reduce((acc, routeKey) => {
59 | acc[routeKey] = routes[routeKey]
60 | return acc
61 | }, {})
62 |
63 | actions.setWebpackConfig({
64 | plugins: [plugins.define({ ROUTES: JSON.stringify(ROUTES) })]
65 | })
66 | }
67 |
68 | exports.onCreatePage = ({ page, actions, reporter }, { routeFilePath }) => {
69 | const { deletePage } = actions
70 |
71 | const { routes } = getDynamicRoutes(routeFilePath)
72 |
73 | const existingRouteOnPageFolder = Object.values(routes).some(
74 | ({ component }) => {
75 | const isSomeRouteThatWillBeRenamed =
76 | path.resolve(component) === page.component
77 | return isSomeRouteThatWillBeRenamed
78 | }
79 | )
80 |
81 | if (existingRouteOnPageFolder) {
82 | deletePage(page)
83 | reporter.info(`Preventing creation of route: ${page.path}`)
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | // no-op
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gatsby-plugin-dynamic-routes",
3 | "version": "1.0.2",
4 | "description": "Creating dynamic routes based on your environment and/or renaming existing routes",
5 | "main": "index.js",
6 | "repository": "git@github.com:luanbitar/gatsby-plugin-dynamic-routes.git",
7 | "author": "Luan Bitar <7@lbitar.com>",
8 | "license": "MIT",
9 | "keywords": [
10 | "gatsby",
11 | "gatsby-plugin",
12 | "plugin",
13 | "routes",
14 | "routing",
15 | "dynamic",
16 | "renaming",
17 | "pages",
18 | "env",
19 | "environment",
20 | "renaming",
21 | "themes",
22 | "organic"
23 | ],
24 | "peerDependencies": {
25 | "gatsby": ">2.0.0"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | dotenv@^8.2.0:
6 | version "8.2.0"
7 | resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a"
8 | integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==
9 |
--------------------------------------------------------------------------------