-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(functions): added functions examples to examples folder. (#31806)
* chore: added functions examples to examples folder. * chore: format * Fix linting Co-authored-by: gatsbybot <[email protected]> Co-authored-by: Sidhartha Chatterjee <[email protected]>
- Loading branch information
1 parent
72d795c
commit ce8e39d
Showing
74 changed files
with
2,280 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
<p align="center"> | ||
<a href="https://www.gatsbyjs.com/?utm_source=starter&utm_medium=readme&utm_campaign=gatsby-functions-beta"> | ||
<img alt="Gatsby" src="https://www.gatsbyjs.com/Gatsby-Monogram.svg" width="60" /> | ||
</a> | ||
</p> | ||
<h1 align="center"> | ||
Gatsby Functions Airtable Form Example | ||
</h1> | ||
|
||
## 🚀 Quick start | ||
|
||
1. Setup Airtable | ||
|
||
Create a new base named `Submissions` and create a table with three columns, "Name", "Email", and "Message". | ||
|
||
2. **Get Airtable Credentials.** | ||
|
||
There are **2** environment variable you'll need to add your project to properly run the example: | ||
|
||
- `AIRTABLE_KEY`: Get Airtable API Key. [Airtable Docs](https://support.airtable.com/hc/en-us/articles/219046777-How-do-I-get-my-API-key-) | ||
- `AIRTABLE_DB`: Get the ID for the "Submissions" Base in interactive Airtable API docs. [Airtable Docs](https://airtable.com/api) | ||
|
||
You'll want to add these as environment variables when deploying to Gatsby Cloud. Don't forget to add them to the Preview variables if you plan to add a CMS preview integration. | ||
|
||
3. **Start developing.** | ||
|
||
To get started, run `yarn` to add all necessary packages. | ||
|
||
When developing locally, you'll want to include the ENV variables in your `.env.development`. Read more about how Gatsby handles `.env` files and environment variables in the [Gatbsy Docs](https://www.gatsbyjs.com/docs/how-to/local-development/environment-variables/) | ||
|
||
```shell | ||
cd airtable-form | ||
yarn | ||
yarn run develop | ||
``` | ||
|
||
4. **Open the code and start customizing!** | ||
|
||
Your site is now running at http://localhost:8000! You can use the UI on the index page to test the functions or directly access them at http://localhost:8000/api/airtable | ||
|
||
For this route, hitting the route with a POST request with the following body should submit a form response to your Airtable base: | ||
|
||
```json | ||
{ | ||
"name": "Sample Name", | ||
"email": "[email protected]", | ||
"message": "Hello, World!" | ||
} | ||
``` | ||
|
||
Edit `src/pages/index.js` to see your site update in real-time! | ||
|
||
5. **Deploy** | ||
|
||
You can deploy this example on Gatsby Cloud by copying the example into a new repo and [connecting that to Gatsby Cloud](https://www.gatsbyjs.com/docs/how-to/previews-deploys-hosting/deploying-to-gatsby-cloud/#set-up-an-existing-gatsby-site). | ||
|
||
<!--- Working on improving deploy now to use subdirectories | ||
4. **Deploy** | ||
You can directly deploy this example by using the Deploy button below and select the directory for the Airtable example. Otherwise, fork this repo and create your own repo and [connect that to Gatsby Cloud](https://www.gatsbyjs.com/docs/how-to/previews-deploys-hosting/deploying-to-gatsby-cloud/#set-up-an-existing-gatsby-site). | ||
[<img src="https://www.gatsbyjs.com/deploynow.svg">](https://www.gatsbyjs.com/dashboard/deploynow?url=https://github.com/gatsbyjs/gatsby-functions-beta/) | ||
[<img src="https://www.gatsbyjs.com/deploynow.svg">](https://www.gatsbyjs.com/dashboard/deploynow?url=https://github.com/gatsbyjs/gatsby-functions-beta/tree/main/examples/airtable-form) | ||
--> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
module.exports = { | ||
flags: { | ||
FUNCTIONS: true, | ||
}, | ||
siteMetadata: { | ||
title: "Airtable Form", | ||
}, | ||
plugins: ["gatsby-plugin-gatsby-cloud"], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"name": "airtable-form", | ||
"version": "1.0.0", | ||
"private": true, | ||
"description": "Airtable Form", | ||
"author": "Joel Smith", | ||
"keywords": [ | ||
"gatsby" | ||
], | ||
"scripts": { | ||
"develop": "gatsby develop", | ||
"start": "gatsby develop", | ||
"build": "gatsby build", | ||
"serve": "gatsby serve", | ||
"clean": "gatsby clean" | ||
}, | ||
"dependencies": { | ||
"airtable": "^0.10.1", | ||
"gatsby": "^3.4.0", | ||
"gatsby-plugin-gatsby-cloud": "^2.3.0", | ||
"react": "^17.0.1", | ||
"react-dom": "^17.0.1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
const Airtable = require("airtable") | ||
|
||
Airtable.configure({ | ||
endpointUrl: "https://api.airtable.com", | ||
//Your API Key from Airtable | ||
apiKey: process.env.AIRTABLE_KEY, | ||
}) | ||
|
||
// Your Table ID from Airtable | ||
const db = Airtable.base(process.env.AIRTABLE_DB) | ||
|
||
const handler = (req, res) => { | ||
try { | ||
if (req.method !== "POST") { | ||
return res.status(404).json({ message: "This endpoint requires a POST" }) | ||
} | ||
|
||
const data = req.body | ||
|
||
if (!data) { | ||
return res.status(500).json({ error: "There isn't any data." }) | ||
} | ||
|
||
db("Submissions").create( | ||
[ | ||
{ | ||
fields: { | ||
Name: data.name, | ||
Email: data.email, | ||
Message: data.message, | ||
}, | ||
}, | ||
], | ||
(err, records) => { | ||
if (err) { | ||
res.json({ | ||
message: "Error adding record to Airtable.", | ||
error: err.message, | ||
}) | ||
} else { | ||
res.json({ message: `Successfully submitted message` }) | ||
} | ||
} | ||
) | ||
} catch (err) { | ||
console.log(err) | ||
res.json({ message: "There has been a big error.", error: err }) | ||
} | ||
} | ||
|
||
module.exports = handler |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import * as React from "react" | ||
import { Link } from "gatsby" | ||
|
||
// styles | ||
const pageStyles = { | ||
color: "#232129", | ||
padding: "96px", | ||
fontFamily: "-apple-system, Roboto, sans-serif, serif", | ||
} | ||
const headingStyles = { | ||
marginTop: 0, | ||
marginBottom: 64, | ||
maxWidth: 320, | ||
} | ||
|
||
const paragraphStyles = { | ||
marginBottom: 48, | ||
} | ||
const codeStyles = { | ||
color: "#8A6534", | ||
padding: 4, | ||
backgroundColor: "#FFF4DB", | ||
fontSize: "1.25rem", | ||
borderRadius: 4, | ||
} | ||
|
||
// markup | ||
const NotFoundPage = () => { | ||
return ( | ||
<main style={pageStyles}> | ||
<title>Not found</title> | ||
<h1 style={headingStyles}>Page not found</h1> | ||
<p style={paragraphStyles}> | ||
Sorry{" "} | ||
<span role="img" aria-label="Pensive emoji"> | ||
😔 | ||
</span>{" "} | ||
we couldn’t find what you were looking for. | ||
<br /> | ||
{process.env.NODE_ENV === "development" ? ( | ||
<> | ||
<br /> | ||
Try creating a page in <code style={codeStyles}>src/pages/</code>. | ||
<br /> | ||
</> | ||
) : null} | ||
<br /> | ||
<Link to="/">Go home</Link>. | ||
</p> | ||
</main> | ||
) | ||
} | ||
|
||
export default NotFoundPage |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import * as React from "react" | ||
|
||
export default function AirtableUI() { | ||
return ( | ||
<form action="/api/airtable" method="POST"> | ||
<h2 style={{ marginBottom: `16px` }}>Add person to Airtable</h2> | ||
<div style={{ marginBottom: `8px` }}> | ||
<label style={{ display: `block`, marginBottom: `4px` }} htmlFor="name"> | ||
Name: | ||
</label> | ||
<input name="name" id="name" /> | ||
</div> | ||
<div style={{ marginBottom: `8px` }}> | ||
<label | ||
style={{ display: `block`, marginBottom: `4px` }} | ||
htmlFor="email" | ||
> | ||
Email: | ||
</label> | ||
<input name="email" id="email" type="email" /> | ||
</div> | ||
<div style={{ marginBottom: `24px` }}> | ||
<label | ||
style={{ display: `block`, marginBottom: `4px` }} | ||
htmlFor="message" | ||
> | ||
Message: | ||
</label> | ||
<textarea name="message" id="message" /> | ||
</div> | ||
<div> | ||
<button>Submit new person</button> | ||
</div> | ||
</form> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
JWT_ISSUER=https://domain-from-auth0-application.com | ||
JWT_AUDIENCE=https://api/tv-shows | ||
GATSBY_AUTH0_DOMAIN=domain-from-auth0-application.com | ||
GATSBY_AUTH0_CLIENT_ID=Copy from Auth0 application | ||
GATSBY_AUTH0_AUDIENCE=https://api/tv-shows | ||
GATSBY_AUTH0_SCOPE=openid profile read:shows |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
The BSD Zero Clause License (0BSD) | ||
|
||
Copyright (c) 2020 Gatsby Inc. | ||
|
||
Permission to use, copy, modify, and/or distribute this software for any | ||
purpose with or without fee is hereby granted. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | ||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR | ||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
PERFORMANCE OF THIS SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# gatsby-auth0-functions | ||
|
||
This example shows how to use [@serverless-jwt](https://github.com/sandrinodimattia/serverless-jwt) with Gatsby and Gatsby Hosted Functions. | ||
|
||
## Inspiration | ||
|
||
This code was inspired by this [article](https://sandrino.dev/blog/securing-netlify-functions-with-serverless-jwt) and [repo](https://github.com/sandrinodimattia/serverless-jwt). | ||
|
||
## 🚀 Quick start | ||
|
||
To test this Example locally you'll need to: | ||
|
||
1. Create an application in [Auth0](https://auth0.com/) of type "Single Page Application" and configure `http://localhost:8000` as the Allowed Callback URL, Allowed Logout URL, Allowed Web Origins and Allowed CORS. | ||
2. Create an API in Auth0 (e.g. with the name of `tv-shows` and identifier of `https://api/tv-shows`) and create a permission for that API (e.g. `read:shows`) | ||
3. Rename the `.env-template` file to `.env.development` and update all of the settings there with the domain and clientId from the appplication you made in Auth0. | ||
4. Run `yarn run start` which will run the Gatsby application and the Gatsby functions. | ||
|
||
## How does example this work? | ||
|
||
### Gatsby | ||
|
||
The Gatsby application uses [@auth0/auth0-react](https://github.com/auth0/auth0-react) to authenticate the user. Once the user is authenticated, the Gatsby application will receive an `id_token` and `access_token` from Auth0; | ||
|
||
The `access_token` is then provided to our Functions to authenticate the request. | ||
|
||
### Gatsby Functions | ||
|
||
In the Gatsby Functions we use [@serverless-jwt/jwt-verifier](https://github.com/sandrinodimattia/serverless-jwt/tree/master/packages/jwt-verifier) to secure our functions. | ||
|
||
The `JwtVerifier` serves as a way to verify your token. If the token is not valid, the we return an error to the client. If it is valid, it will expose all of the claims to the current function and you'll have the guarantee that the request is authenticated. | ||
|
||
```js | ||
const { | ||
JwtVerifier, | ||
getTokenFromHeader, | ||
} = require("@serverless-jwt/jwt-verifier") | ||
|
||
const jwt = new JwtVerifier({ | ||
issuer: process.env.JWT_ISSUER, | ||
audience: process.env.JWT_AUDIENCE, | ||
}) | ||
|
||
const shows = async (req, res) => { | ||
const scope = "read:shows" | ||
const token = getTokenFromHeader(req.get("authorization")) | ||
const claims = await jwt.verifyAccessToken(token) | ||
|
||
if (!claims || !claims.scope || claims.scope.indexOf(scope) === -1) { | ||
return res.status(403).json({ | ||
error: "access_denied", | ||
error_description: `Token does not contain the required '${scope}' scope`, | ||
}) | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import React from "react" | ||
import { navigate } from "gatsby" | ||
import { Auth0Provider } from "@auth0/auth0-react" | ||
|
||
import "./src/styles/site.css" | ||
|
||
const onRedirectCallback = appState => navigate(appState?.returnTo || "/") | ||
|
||
export const wrapRootElement = ({ element }) => { | ||
return ( | ||
<Auth0Provider | ||
domain={process.env.GATSBY_AUTH0_DOMAIN} | ||
clientId={process.env.GATSBY_AUTH0_CLIENT_ID} | ||
audience={process.env.GATSBY_AUTH0_AUDIENCE} | ||
scope={process.env.GATSBY_AUTH0_SCOPE} | ||
redirectUri={window.location.origin} | ||
onRedirectCallback={onRedirectCallback} | ||
> | ||
{element} | ||
</Auth0Provider> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
const activeEnv = | ||
process.env.GATSBY_ACTIVE_ENV || process.env.NODE_ENV || "development" | ||
|
||
require("dotenv").config({ | ||
path: `.env.${activeEnv}`, | ||
}) | ||
|
||
module.exports = { | ||
flags: { | ||
FUNCTIONS: true, | ||
}, | ||
plugins: [ | ||
{ | ||
resolve: "gatsby-plugin-create-client-paths", | ||
options: { prefixes: ["/*"] }, | ||
}, | ||
`gatsby-plugin-postcss`, | ||
`gatsby-plugin-gatsby-cloud`, | ||
], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{ | ||
"name": "gatsby-auth0-functions", | ||
"private": true, | ||
"scripts": { | ||
"build": "gatsby build", | ||
"develop": "gatsby develop", | ||
"start": "npm run develop", | ||
"serve": "gatsby serve", | ||
"clean": "gatsby clean" | ||
}, | ||
"dependencies": { | ||
"@auth0/auth0-react": "^1.0.0", | ||
"@serverless-jwt/jwt-verifier": "^0.2.1", | ||
"dotenv": "^8.2.0", | ||
"gatsby": "^3.4.0-next.6", | ||
"gatsby-plugin-gatsby-cloud": "^2.3.0", | ||
"node-fetch": "^2.6.1", | ||
"react": "^17.0.2", | ||
"react-dom": "^17.0.2" | ||
}, | ||
"devDependencies": { | ||
"gatsby-plugin-create-client-paths": "^3.3.0", | ||
"gatsby-plugin-postcss": "^4.3.0", | ||
"prettier": "^2.2.1", | ||
"tailwindcss": "^1.5.2" | ||
} | ||
} |
Oops, something went wrong.