Edward Jackson

Edward Jackson

1566351992

Build a Performant Infinite Scroll Image Gallery using Gatsby and Netlify functions

Originally published by William Imoh at https://scotch.io

What's the trend about static sites and decoupled development architectures with the JAMStack? Why are top sites and apps moving to build with "static site generators"? It's speed, security, affordability, developer experience and much more. We are here for it all. 

Static sites are known over time as fast sites which serve static content from a CDN without any web server or API interaction. Modern build tools currently furnish sites with the speed and security of static sites along with the dynamism of fetching and interacting with data from APIs during runtime.

Table of Contents

  • TL : DR
  • Why Gatsby?
  • Why Netlify?
  • Installation
  • Project Structure
  • Configure Site Layout
  • Create Site Pages
  • Create The Image Gallery
  • Create The Netlify Function
  • Deploying to Netlify
  • Conclusion 

TL : DR

In this post, we will:

  • Setup a Gatsby site locally using the Gatsby CLI.
  • Create pages in the Gatsby site.
  • Handle consistent layout across the site.
  • Create an Infinite Scroll Image masonry.
  • Create a Netlify function to fetch Images.
  • Deploy and consume Netlify functions locally.
  • Render fetched images in a grid gallery.
  • Configure netlify.toml file.
  • Deploy the app to Netlify.

Why Gatsby?

Gatsby is an open-source static site generator for building modern static sites. Gatsby offers the ability to build performant, secure and affordable deployable sites. Absolving the need for a web server, this mitigates the risk of security breaches pertinent to web servers. Gatsby also offers the rich developer experience by way of building the sites in React.js, thus merging the existing vibrant React.js ecosystem.

Since developing with Gatsby is done in React, application logic including server calls can be written in the component lifecycle methods or even as application-wide logic. These will be executed at runtime, hence the notion "Static-Dynamic". On the data layer of Gatsby applications, Gatsby uses GraphQL to make data queries.

Other static site generators abound the internet which allows the creation of static sites, the question is, how efficient are they at building these sites? With the Gatsby CLI, creating an optimized single-paged app is a command away, with little effort put towards performance optimizations.

Why Netlify?

Netlify offers a rich deployment experience for modern applications. Touting an intuitive CI/CD platform as well as utilizing and managing AWS Lambda functions directly on Netlify, deploying static-dynamic applications as we would in this tutorial becomes seamless.

In this post, we would create a netlify function to fetch images using the Unsplash API. This lambda function will be tested locally using netlify-lambda and deployed alongside the application to Netlify.

Functions ship with a memory capacity of 128MB, this is just enough to handle our use case, however for more computational power and workload, you can increase the memory capacity of your functions.

Here's what we'll be building in this article:

Installation

For this tutorial, knowledge of HTML, CSS, JavaScript, and React is required.

Node.js and its package manager NPM is required for this app. Check if you have them installed with:

node -v && npm -v

This command would output the versions of both node and npm. If not installed, proceed to Nodejs.org to download and install node and its package manager.

Install the Gatsby CLI globally with:

npm i -g gatsby-cli

Once the CLI tool is installed, open a new folder and create a new Gatsby project using the default starter. Do this with:

gatsby new gastify

This command clones the default Gatsby starter into the folder and installs all required dependencies specified in the project.

Gatsby ships with starters which are preset websites or apps with which you can quickly build your site off.

Change directory to the project directory and install the required dependencies with:

cd gastify && npm i --save axios bulma react-infinite-scroll-component

Here's a summary of the components:

Once these are installed, start a development server with:

gatsby develop

This spins up a dev server on localhost:8000. Gatsby ships with a hot reloading feature, so any changes to the source file reload the page in the browser instantaneously.

The Gatsby project currently contains default files and configuration shipped with the starter. We will proceed to develop the layout and style.

Project Structure

Everything in Gatsby, just like React, is a component. Gatsby is unique in the way that it serves individually exported JS files in the src/pages folder as a page in the app. Each page can be navigated to using the <Link/> component in Gatsby.

In this project, individual components are written in src/components. Each exported component can be reused in the entirety of the app.

Gatsby provides other default files to extend the functionality further or configure the app. gatsby-config.js contains the config for all plugins used in the app. Those currently installed and configured were shipped along with the default starter.

Configure Site Layout

The site layout will be developed as a component and reused across the application. The components/layout.js file currently exports the layout of the app as designed in the starter. Remove all the content of the layout.js file, import all required dependencies and components with:

import React from "react"
import PropTypes from "prop-types"
import { useStaticQuery, graphql } from "gatsby"

import Header from “./header”

Here, React and prop-types were imported alongside useStaticQuery and GraphQL. useStaticQuery, shipped in Gatsby v2 allows us to make GraphQL data queries in non-page components. This data fetching is static and happens during build, hence the term Static Query.

The Header component which houses the navbar is also imported in the component. This Header component will be created shortly. Define and export the Layout component with the following:

const Layout = ({ children }) => {
 const data = useStaticQuery(graphqlquery SiteTitleQuery { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;site { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;siteMetadata { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;title &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;})

 return (
   <>
     <Header siteTitle={data.site.siteMetadata.title} />
     <div
       style={{
         margin: 0 auto,
         maxWidth: 900,
         padding: 0px 1.0875rem 1.45rem,
         paddingTop: 0,
       }}
     >
       <main>{children}</main>
     </div>
   </>
 )
}

Layout.propTypes = {
 children: PropTypes.node.isRequired,
}

export default Layout

Here the useStaticQuery hook is used to fetch the site title from the siteMetadata. This siteTitle is subsequently passed in the header component as props. The base style for the div enclosing the children of the layout is also configured.

Go on ahead to gatsby-config.js in the root directory to change the site title and description. Modify the siteMetada property to:

siteMetadata: {
   title: Gastify,
   description: Here lies a doggo Infinite scroll Image gallery built with Gatsby, Netlify Functions and the Unsplash API,
   author: @iChuloo,
 },

In components/header.js, import the required modules and components with:

import { Link } from “gatsby”
import PropTypes from “prop-types”
import React from “react”

Create the Header functional component which defines a siteTitle prop with:

const Header = ({ siteTitle }) => (
 <header>
   <nav className=“navbar is-dark” style={{ marginBottom: “2em” }}>
     <div className=“navbar-brand”>
       <Link
         to=“/”
         style={{
           marginLeft: “3em”,
           padding: “10px”,
         }}
         className=“has-text-white is-size-3”
       >
         {siteTitle} 🐶
       </Link>
     </div>
     <div className=“navbar-end” style={{ marginRight: “3em” }}>
       <div className=“navbar-item”>
         <Link
           to=“/”
           style={{
             padding: “10px”,
           }}
           className=“has-text-white”
         >
           Home
         </Link>
         <Link
           to=“/gallery/”
           style={{
             padding: “10px”,
           }}
           className=“has-text-white”
         >
           Gallery
         </Link>
       </div>
     </div>
   </nav>
 </header>
)

export default Header

Two routes were designated in the navbar, while / directs to the homepage, /gallery/ directs to the gallery page to be created shortly. The <Link/> component shipped with gatsby is used to navigate the routes in the single-paged app and ships with its own to attribute which accepts the slug of the route.

Bulma classes were used to style this component. For Bulma to work, we will import it in the index.js page shortly.

Next, we will utilize this layout component on the homepage.

Create Site Pages

Home Page

In src/pages/index.js, wipe the default starter code in the file and import required dependencies and components with:

import React from “react”
import { Link } from “gatsby”
import Layout from “…/components/layout”
import SEO from “…/components/seo”
import “bulma/css/bulma.min.css”

Notice how the minified Bulma CSS file was imported. Also, the Layout component was imported alongside the SEO component, which was included in the starter by default.

Define and export the page using the imported components with:

const IndexPage = () => (
 <Layout>
   <SEO title=“Home” />
   <div className=“has-text-centered” style={{ marginTop: “20%” }}>
     <h1 className=“is-size-2”>Welcome to Pride Rock! . . . or nah 😹</h1>
     <p className=“is-size-5” style={{ marginTop: “2%” }}>
       Find within, a fire doggo infinite image gallery built with Gatsby, and
       Images served using Netlify functions from Unsplash. Perfecto!
     </p>
     <button className=“button is-dark is-large” style={{ marginTop: “10%” }}>
       <Link to=“/gallery/” className=“has-text-white”>
         Open Sesame! 🔥
       </Link>
     </button>
   </div>
 </Layout>
)

export default IndexPage

Bulma classes were also used to style this page.

Gallery Page

In the same src/pages directory, create a new folder named gallery.js. Similar to the index page, import the SEO component as well as the Layout component. Do this with:

import React from “react”
import Layout from “…/components/layout”
import SEO from “…/components/seo”

Create and export the page component with:

const Gallery = () => {
 return (
   <Layout>
     <SEO title=“Gallery” />
     <h1 className=“is-size-3”>Images from Unsplash…</h1>
     <p style={{ marginBottom: “5%” }}>
       Now this is the Law of the Jungle, as old and true as the sky, for as
       long as you keep scrolling, you shall find more doggo images 🐶 🐕.
     </p>
   </Layout>
 )
}

export default Gallery

Once you save the page, the browser should refresh with the complete pages though the gallery page will only have the text and no images yet.

You can restart the dev server to rebuild.

Create The Image Gallery

Like we stated earlier, the good thing about building with tools like Gatsby is we can make API calls in components and pass the data to the DOM during runtime, giving the experience of a dynamic app in a static environment. The react-infinite-scroll-component will be used to create the infinite scroll whereas the Images will be fetched from Unsplash using netlify functions.

In src/components create a new component named InfiniteImages.js. In the component, import the required dependencies with:

import React from “react”
import PropTypes from “prop-types”
import InfiniteScroll from “react-infinite-scroll-component”

For this gallery, we’ll need two components:

  1. A component to hold the Image gallery view.
  2. A component to handle state, data fetching and propagation to the Image gallery view.

These components can be split into further subcomponents but for the sake of simplicity, we’ll leave it at these two and even have them co-located in the same file.

In InfiniteImages.js, create a functional component after the dependency imports named ImageGallery. This is the gallery view. Define the components to accept props of images, loading, and fetchImages. Do this with:

import …

const ImageGallery = ({ images, loading, fetchImages }) => {
 // Create gallery here
 return (
   <InfiniteScroll
     dataLength={images.length}
     next={() => fetchImages()}
     hasMore={true}
     loader={
       <p style={{ textAlign: “center”, marginTop: “1%” }}>
         More doggo incoming 🐕 🐕…
       </p>
     }
   >
     <div className=“image-grid”>
       {!loading
         ? images.map(image => (
             <div className=“image-item” key={image.id}>
               <img src={image.urls.regular} alt={image.alt_description} />
             </div>
           ))
         : “”}
     </div>
   </InfiniteScroll>
 )
}

The InfiniteScroll component imported takes props of:

  • dataLength: The length of the rendered data.
  • next: A function to be called once a scroll threshold is reached.
  • hasMore: A boolean to indicate the existence of more data to be rendered on fetch.
  • Loader: A component or string to the displayed when images are being fetched.

In the infinite scroll, the array of images passed through the images prop is traversed and Images rendered in a grid. Properties of each image object are passed as data to the key, alt value and ultimately the image src.

The masonry is styled with css-grid. Create a custom CSS file named gallery.css in the components folder and edit it to:

.image-grid {
 display: grid;
 grid-gap: 10px;
 grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
 grid-auto-rows: minmax(50px, auto);
}

.image-grid .image-item:nth-child(5n) {
 grid-column-end: span 2;
}

.image-grid img {
 display: flex;
 width: 100%;
 height: 100%;
 object-fit: cover;
}

Import the CSS file to the InfiniteImages.js component with:

import “./gallery.css”

With the view complete, let’s set up the parent component handling fetch from the API.

Create a component in InfiniteImages.js named InfiniteImages.

This functional component uses the React useState and useEffect hooks to handle state and lifecycle computation, respectively. Axios is also used to make HTTP requests. Import Axios and the hooks in InfiniteImages.js with:

import React, { useState, useEffect } from “react”
import axios from “axios”

// Component logic below

With hooks imported, define the InfiniteImage component with:

const InfiniteImages = () => {
 // Hold state
 const [images, setImages] = useState([])
 const [loading, setLoading] = useState(true)

 // Fetch images on component mount
 useEffect(() => {
   fetchImages()
 }, [])

   // API endpoint
   const endpoint = “<Endpoint here once available>”

   // Fetch Images from functions
 const fetchImages = () => {
   axios(endpoint).then(res => {
     setImages([…images, …res.data.images])
     setLoading(false)
   })
 }
 return (
   <ImageGallery images={images} loading={loading} fetchImages={fetchImages} />
 )
}

Here, we created state variables to hold the fetched images and also to store the state of the fetch operation. The images variable defaults to an empty array while the loading variable defaults to true as we assume by default, the images are loading once the component mounts.

The useEffect hook is used to call the fetchImages function once the component is mounted. An empty array as a second argument signifies that the function will only run when the component mounts.

A fetchImages function is created which uses axios to make a GET request to a specified API. The returned data is spread in the images array in state. Thus any new data fetched is added to existing ones in state. The loading variable is also set to false as the fetch operation is complete.

The ImageGallery component earlier created is used to render the gallery with the required data.

Assign the Proptypes to the ImageGallery component and export the InfiniteImage module with:

import…

const ImageGallery = ({ images, loading, fetchImages }) => {
 // Create gallery here
 return (
   // Component logic here
 )
}

const InfiniteImages = () => {
 // Component logic here
}

ImageGallery.propTypes = {
 images: PropTypes.array,
 loading: PropTypes.bool,
 fetchImages: PropTypes.func,
}

export default InfiniteImages

With this, we have the gallery set up, what’s missing is the API endpoint. We’ll proceed to define a Netlify function to handle that.

Create The Netlify Function

Netlify functions are AWS lambdas managed directly on Netlify. With this, we abstract the management and scaling of a traditional server. Multiple functions can be created and used across an application after the application is built.

These functions in JavaScript are .js files stored in any designated directory in the project’s repository and specified on Netlify or in the netlify.toml config file in the root directory of a project.

Creating a Netlify function is seamless. It is either created in a functions directory or a build tool is used to create the function from a source folder into the functions folder.

If you are familiar with backend development, creating node servers and APIs would probably be a breeze, for Netlify Functions written in JavaScript, knowledge of Nodejs is not compulsory as Netlify ships Netlify-lambda. This is a tool to help with building Netlify functions from modern JavaScript workflows using webpack/babel.

We will employ this in this tutorial to build functions written in ES6 syntax into a functions directory.

For this gallery, we will query a free Unsplash API to obtain super cute images of dogs and display them in a masonry. Head to Unsplash, signup to create a new app and get an access key.

While this API can be consumed directly in the app, we would like to abstract this image fetching process to our API, thus securing access/private keys or any other backend logic. In other applications, business or other logic can also go in our API.

Install Functions Build tool

netlify-lambda CLI is used to run functions locally as well as create a deployable build. These functions can be written with modern JS workflows before being bundled into a single build using webpack/babel. For this project, we’ll create a folder to house the locally written functions as well as the deployable functions. 

Install the netlify-lambda CLI with:

npm i -g netlify-lambda

With this we can serve the functions locally with:

netlify-lambda serve <path-to-source-folder>

A deployable build can be created with :

netlify-lambda build <path-to-source-folder>

Create a Function and Source Directory

Create a folder in the src directory named lambda. This serves as the source folder will contain all the functions as written. Create a second folder in the root directory of the project named functions. This, in turn, will hold all deployable functions. For Netlify to recognize the functions folder, we need to specify it in the Netlify config file. Create a file in the root directory of the project named netlify.toml. Add this config with:

[build]
 Functions = “functions”

This specifies that the functions for the app can be found in the functions directory in the app root. Once this app is deployed, each function will be available on:

https://<root-url-of-app>/.netlify/functions/<function-name>

Define The Fetch Function

Lambda functions are JS files which export a handler method. Each function takes three parameters:

  • event: This is an object received when the function is triggered.
  • context: This contains the conditions in which the function was called.
  • callback: This is returned on function execution and contains the error if any, as the first parameter. It also contains a response payload as the second.

In the project, create a file named fetch.js in src/lambda, configure the function with:

import axios from “axios”
import config from “…/…/config”

exports.handler = function(event, context, callback) {
 const apiRoot = “https://api.unsplash.com
 const accessKey = process.env.ACCESS_KEY || config.accessKey

 const doggoEndpoint = ${apiRoot}/photos/random?client_id=${accessKey}&amp;count=${10}&amp;collections='3816141,1154337,1254279'

 axios.get(doggoEndpoint).then(res => {
   callback(null, {
     statusCode: 200,
     body: JSON.stringify({
       images: res.data,
     }),
   })
 })
}

In here, axios which is imported is used to make an API call to the Unsplash API, and the returned data is sent in the callback with a status code of 200. The API Key will be stored as an environment variable on Netlify and also in a config file for local usage.

Create a file named config.js in the root directory and add the API key from Unsplash with:

const config = {
 accessKey: “<Add access key>”,
}

export default config

Be sure to add the config file to .gitignore so it’s not added to your repository if public.

State a dev server for the functions with:

netlify-lambda serve src/lambda

This creates a server on http://localhost:9000.

Navigate to http://localhost:9000/fetch to see the data fetched from the API being displayed on the browser. 

To create a build in the functions folder, run:

netlify-lambda build src/lambda

This creates a build in the functions folder ready to be deployed.

We have the functions set up and running, let’s configure it for local usage.

Configure Function for Local Usage

Using the function as is in the local dev server on Gatsby would throw a CORS error. Advanced proxying in Gatsby.js, affords us the ability to use a proxy middleware to proxy the functions in our local environment consequently bypassing CORS. Install http-proxy-middleware with:

npm i --save-dev http-proxy-middleware

Configure the proxy middleware in gatsby-config.js with:

let proxy = require(“http-proxy-middleware”)

module.exports = {
 siteMetadata: {
   // define site metadata
 },
 // Enables the use of function URLs locally
 developMiddleware: app => {
   app.use(
     “/.netlify/functions/”,
     proxy({
       target: “http://localhost:9000”,
       pathRewrite: { “/.netlify/functions/”: “” },
     })
   )
 },
 plugins: [
   // define plugins
 ],
}

The /.netlify/functions/ endpoint in development is proxied to http://local:9000 and the path is re-written, this way http://localhost:9000/fetch becomes /.netlify/functions/fetch which is also the valid local endpoint for the function.

Pass the API endpoint to the axios request in the InfiniteImages function in src/components/InfiniteImages.js. Do this with:

import // …

const ImageGallery = ({ images, loading, fetchImages }) => {
 // Component logic here
}

const InfiniteImages = () => {
 // Hold state
 const [images, setImages] = useState([])
 const [loading, setLoading] = useState(true)

 // Fetch images on component mount
 useEffect(() => {
   fetchImages()
 }, [])

 // Fetch Images from functions
 const fetchImages = () => {
   axios(“/.netlify/functions/fetch”).then(res => {
     setImages([…images, …res.data.images])
     setLoading(false)
   })
 }
 return (
   <ImageGallery images={images} loading={loading} fetchImages={fetchImages} />
 )
}

ImageGallery.propTypes = {
   // Define proptypes
}

export default InfiniteImages

Restart the Gatsby dev server, while ensuring the server of the local function is running. Here’s what the app looks now:

Deploying to Netlify

At this point, the app works on our local environment. Before deploying to Netlify, re-build the functions with:

netlify-lambda build src/lambda

Run a Gatsby build to verify the build process works without errors. Do this with:

gatsby build

Next is to deploy to a Git provider.

Push to Git Provider

Create a new repository on a remote git provider. Initialize the repository on your local machine, stage all your files, commit and push to the new remote repository.

Ensure the config.js file in the root directory is added to .gitignore.

Deploy On Netlify

Go on to Netlify and create an account. Use the “New site from Git” button to add a new site.

On the “Connect to Git Provider” tab, select GitHub or whichever provider you used and authorize your account. In the next tab, pick the repository you deployed to or use the search function to search for the repository.

Configure the deploy settings with the build command as gatsby build and publish directory as public. Click the “Show advanced” button then the “new variable” button to add a new environment variable.

Hit the “Deploy site” button to deploy.

Netlify deploys the site and utilizes the functions in the functions directory after build. These functions are not exposed on the client side except the functions directory is in the publish directory.

Note that the build command, publish directory and environment variables can also be set in the netlify.toml file of the project.

You can find the final deployed site at https://gastify.netlify.com

You can find the repository here: https://github.com/Chuloo/gatsby-netlify-functions

Here’s a peek on lighthouse audit scores of the deployed site:

Conclusion

In this post, we saw an overview of static sites, their features, importance, going dynamic with fetching dynamic content using serverless functions and an overview of serverless functions.




#web-development #javascript #node-js #reactjs #graphql

What is GEEK

Buddha Community

Build a Performant Infinite Scroll Image Gallery using Gatsby and Netlify functions

I am Developer

1597469369

Crop and Resize Image Before Upload In Laravel Using with jQuery Copper JS

Crop and resize image size before upload in laravel using jquery copper js. In this post, i will show you how to crop and resize image size in laravel using jQuery copper js in laravel.

This laravel crop image before upload using cropper js looks like:

laravel crop image before upload

Laravel Crop Image Before Uploading using Cropper js Tutorial

Laravel crop image before upload tutorial, follow the following steps and learn how to use cropper js to crop image before uploading in laravel app:

  • Step 1: Install New Laravel App
  • Step 2: Add Database Details
  • Step 3: Create Migration & Model
  • Step 4: Add Route
  • Step 5: Create Controller By Artisan
  • Step 6: Create Blade View
  • Step 7: Make Upload Directory
  • Step 8: Start Development Server

Read More => https://www.tutsmake.com/laravel-crop-image-before-upload-using-jquery-copper-js/

Live Demo Laravel Crop image Before Upload.

#laravel crop image before upload, #laravel crop and resize image using cropper.js #ajax image upload and crop with jquery and laravel #crop and upload image ajax jquery laravel #crop image while uploading with jquery laravel #image crop and upload using jquery with laravel ajax

Edward Jackson

Edward Jackson

1566351992

Build a Performant Infinite Scroll Image Gallery using Gatsby and Netlify functions

Originally published by William Imoh at https://scotch.io

What's the trend about static sites and decoupled development architectures with the JAMStack? Why are top sites and apps moving to build with "static site generators"? It's speed, security, affordability, developer experience and much more. We are here for it all. 

Static sites are known over time as fast sites which serve static content from a CDN without any web server or API interaction. Modern build tools currently furnish sites with the speed and security of static sites along with the dynamism of fetching and interacting with data from APIs during runtime.

Table of Contents

  • TL : DR
  • Why Gatsby?
  • Why Netlify?
  • Installation
  • Project Structure
  • Configure Site Layout
  • Create Site Pages
  • Create The Image Gallery
  • Create The Netlify Function
  • Deploying to Netlify
  • Conclusion 

TL : DR

In this post, we will:

  • Setup a Gatsby site locally using the Gatsby CLI.
  • Create pages in the Gatsby site.
  • Handle consistent layout across the site.
  • Create an Infinite Scroll Image masonry.
  • Create a Netlify function to fetch Images.
  • Deploy and consume Netlify functions locally.
  • Render fetched images in a grid gallery.
  • Configure netlify.toml file.
  • Deploy the app to Netlify.

Why Gatsby?

Gatsby is an open-source static site generator for building modern static sites. Gatsby offers the ability to build performant, secure and affordable deployable sites. Absolving the need for a web server, this mitigates the risk of security breaches pertinent to web servers. Gatsby also offers the rich developer experience by way of building the sites in React.js, thus merging the existing vibrant React.js ecosystem.

Since developing with Gatsby is done in React, application logic including server calls can be written in the component lifecycle methods or even as application-wide logic. These will be executed at runtime, hence the notion "Static-Dynamic". On the data layer of Gatsby applications, Gatsby uses GraphQL to make data queries.

Other static site generators abound the internet which allows the creation of static sites, the question is, how efficient are they at building these sites? With the Gatsby CLI, creating an optimized single-paged app is a command away, with little effort put towards performance optimizations.

Why Netlify?

Netlify offers a rich deployment experience for modern applications. Touting an intuitive CI/CD platform as well as utilizing and managing AWS Lambda functions directly on Netlify, deploying static-dynamic applications as we would in this tutorial becomes seamless.

In this post, we would create a netlify function to fetch images using the Unsplash API. This lambda function will be tested locally using netlify-lambda and deployed alongside the application to Netlify.

Functions ship with a memory capacity of 128MB, this is just enough to handle our use case, however for more computational power and workload, you can increase the memory capacity of your functions.

Here's what we'll be building in this article:

Installation

For this tutorial, knowledge of HTML, CSS, JavaScript, and React is required.

Node.js and its package manager NPM is required for this app. Check if you have them installed with:

node -v && npm -v

This command would output the versions of both node and npm. If not installed, proceed to Nodejs.org to download and install node and its package manager.

Install the Gatsby CLI globally with:

npm i -g gatsby-cli

Once the CLI tool is installed, open a new folder and create a new Gatsby project using the default starter. Do this with:

gatsby new gastify

This command clones the default Gatsby starter into the folder and installs all required dependencies specified in the project.

Gatsby ships with starters which are preset websites or apps with which you can quickly build your site off.

Change directory to the project directory and install the required dependencies with:

cd gastify && npm i --save axios bulma react-infinite-scroll-component

Here's a summary of the components:

Once these are installed, start a development server with:

gatsby develop

This spins up a dev server on localhost:8000. Gatsby ships with a hot reloading feature, so any changes to the source file reload the page in the browser instantaneously.

The Gatsby project currently contains default files and configuration shipped with the starter. We will proceed to develop the layout and style.

Project Structure

Everything in Gatsby, just like React, is a component. Gatsby is unique in the way that it serves individually exported JS files in the src/pages folder as a page in the app. Each page can be navigated to using the <Link/> component in Gatsby.

In this project, individual components are written in src/components. Each exported component can be reused in the entirety of the app.

Gatsby provides other default files to extend the functionality further or configure the app. gatsby-config.js contains the config for all plugins used in the app. Those currently installed and configured were shipped along with the default starter.

Configure Site Layout

The site layout will be developed as a component and reused across the application. The components/layout.js file currently exports the layout of the app as designed in the starter. Remove all the content of the layout.js file, import all required dependencies and components with:

import React from "react"
import PropTypes from "prop-types"
import { useStaticQuery, graphql } from "gatsby"

import Header from “./header”

Here, React and prop-types were imported alongside useStaticQuery and GraphQL. useStaticQuery, shipped in Gatsby v2 allows us to make GraphQL data queries in non-page components. This data fetching is static and happens during build, hence the term Static Query.

The Header component which houses the navbar is also imported in the component. This Header component will be created shortly. Define and export the Layout component with the following:

const Layout = ({ children }) => {
 const data = useStaticQuery(graphqlquery SiteTitleQuery { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;site { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;siteMetadata { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;title &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;})

 return (
   <>
     <Header siteTitle={data.site.siteMetadata.title} />
     <div
       style={{
         margin: 0 auto,
         maxWidth: 900,
         padding: 0px 1.0875rem 1.45rem,
         paddingTop: 0,
       }}
     >
       <main>{children}</main>
     </div>
   </>
 )
}

Layout.propTypes = {
 children: PropTypes.node.isRequired,
}

export default Layout

Here the useStaticQuery hook is used to fetch the site title from the siteMetadata. This siteTitle is subsequently passed in the header component as props. The base style for the div enclosing the children of the layout is also configured.

Go on ahead to gatsby-config.js in the root directory to change the site title and description. Modify the siteMetada property to:

siteMetadata: {
   title: Gastify,
   description: Here lies a doggo Infinite scroll Image gallery built with Gatsby, Netlify Functions and the Unsplash API,
   author: @iChuloo,
 },

In components/header.js, import the required modules and components with:

import { Link } from “gatsby”
import PropTypes from “prop-types”
import React from “react”

Create the Header functional component which defines a siteTitle prop with:

const Header = ({ siteTitle }) => (
 <header>
   <nav className=“navbar is-dark” style={{ marginBottom: “2em” }}>
     <div className=“navbar-brand”>
       <Link
         to=“/”
         style={{
           marginLeft: “3em”,
           padding: “10px”,
         }}
         className=“has-text-white is-size-3”
       >
         {siteTitle} 🐶
       </Link>
     </div>
     <div className=“navbar-end” style={{ marginRight: “3em” }}>
       <div className=“navbar-item”>
         <Link
           to=“/”
           style={{
             padding: “10px”,
           }}
           className=“has-text-white”
         >
           Home
         </Link>
         <Link
           to=“/gallery/”
           style={{
             padding: “10px”,
           }}
           className=“has-text-white”
         >
           Gallery
         </Link>
       </div>
     </div>
   </nav>
 </header>
)

export default Header

Two routes were designated in the navbar, while / directs to the homepage, /gallery/ directs to the gallery page to be created shortly. The <Link/> component shipped with gatsby is used to navigate the routes in the single-paged app and ships with its own to attribute which accepts the slug of the route.

Bulma classes were used to style this component. For Bulma to work, we will import it in the index.js page shortly.

Next, we will utilize this layout component on the homepage.

Create Site Pages

Home Page

In src/pages/index.js, wipe the default starter code in the file and import required dependencies and components with:

import React from “react”
import { Link } from “gatsby”
import Layout from “…/components/layout”
import SEO from “…/components/seo”
import “bulma/css/bulma.min.css”

Notice how the minified Bulma CSS file was imported. Also, the Layout component was imported alongside the SEO component, which was included in the starter by default.

Define and export the page using the imported components with:

const IndexPage = () => (
 <Layout>
   <SEO title=“Home” />
   <div className=“has-text-centered” style={{ marginTop: “20%” }}>
     <h1 className=“is-size-2”>Welcome to Pride Rock! . . . or nah 😹</h1>
     <p className=“is-size-5” style={{ marginTop: “2%” }}>
       Find within, a fire doggo infinite image gallery built with Gatsby, and
       Images served using Netlify functions from Unsplash. Perfecto!
     </p>
     <button className=“button is-dark is-large” style={{ marginTop: “10%” }}>
       <Link to=“/gallery/” className=“has-text-white”>
         Open Sesame! 🔥
       </Link>
     </button>
   </div>
 </Layout>
)

export default IndexPage

Bulma classes were also used to style this page.

Gallery Page

In the same src/pages directory, create a new folder named gallery.js. Similar to the index page, import the SEO component as well as the Layout component. Do this with:

import React from “react”
import Layout from “…/components/layout”
import SEO from “…/components/seo”

Create and export the page component with:

const Gallery = () => {
 return (
   <Layout>
     <SEO title=“Gallery” />
     <h1 className=“is-size-3”>Images from Unsplash…</h1>
     <p style={{ marginBottom: “5%” }}>
       Now this is the Law of the Jungle, as old and true as the sky, for as
       long as you keep scrolling, you shall find more doggo images 🐶 🐕.
     </p>
   </Layout>
 )
}

export default Gallery

Once you save the page, the browser should refresh with the complete pages though the gallery page will only have the text and no images yet.

You can restart the dev server to rebuild.

Create The Image Gallery

Like we stated earlier, the good thing about building with tools like Gatsby is we can make API calls in components and pass the data to the DOM during runtime, giving the experience of a dynamic app in a static environment. The react-infinite-scroll-component will be used to create the infinite scroll whereas the Images will be fetched from Unsplash using netlify functions.

In src/components create a new component named InfiniteImages.js. In the component, import the required dependencies with:

import React from “react”
import PropTypes from “prop-types”
import InfiniteScroll from “react-infinite-scroll-component”

For this gallery, we’ll need two components:

  1. A component to hold the Image gallery view.
  2. A component to handle state, data fetching and propagation to the Image gallery view.

These components can be split into further subcomponents but for the sake of simplicity, we’ll leave it at these two and even have them co-located in the same file.

In InfiniteImages.js, create a functional component after the dependency imports named ImageGallery. This is the gallery view. Define the components to accept props of images, loading, and fetchImages. Do this with:

import …

const ImageGallery = ({ images, loading, fetchImages }) => {
 // Create gallery here
 return (
   <InfiniteScroll
     dataLength={images.length}
     next={() => fetchImages()}
     hasMore={true}
     loader={
       <p style={{ textAlign: “center”, marginTop: “1%” }}>
         More doggo incoming 🐕 🐕…
       </p>
     }
   >
     <div className=“image-grid”>
       {!loading
         ? images.map(image => (
             <div className=“image-item” key={image.id}>
               <img src={image.urls.regular} alt={image.alt_description} />
             </div>
           ))
         : “”}
     </div>
   </InfiniteScroll>
 )
}

The InfiniteScroll component imported takes props of:

  • dataLength: The length of the rendered data.
  • next: A function to be called once a scroll threshold is reached.
  • hasMore: A boolean to indicate the existence of more data to be rendered on fetch.
  • Loader: A component or string to the displayed when images are being fetched.

In the infinite scroll, the array of images passed through the images prop is traversed and Images rendered in a grid. Properties of each image object are passed as data to the key, alt value and ultimately the image src.

The masonry is styled with css-grid. Create a custom CSS file named gallery.css in the components folder and edit it to:

.image-grid {
 display: grid;
 grid-gap: 10px;
 grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
 grid-auto-rows: minmax(50px, auto);
}

.image-grid .image-item:nth-child(5n) {
 grid-column-end: span 2;
}

.image-grid img {
 display: flex;
 width: 100%;
 height: 100%;
 object-fit: cover;
}

Import the CSS file to the InfiniteImages.js component with:

import “./gallery.css”

With the view complete, let’s set up the parent component handling fetch from the API.

Create a component in InfiniteImages.js named InfiniteImages.

This functional component uses the React useState and useEffect hooks to handle state and lifecycle computation, respectively. Axios is also used to make HTTP requests. Import Axios and the hooks in InfiniteImages.js with:

import React, { useState, useEffect } from “react”
import axios from “axios”

// Component logic below

With hooks imported, define the InfiniteImage component with:

const InfiniteImages = () => {
 // Hold state
 const [images, setImages] = useState([])
 const [loading, setLoading] = useState(true)

 // Fetch images on component mount
 useEffect(() => {
   fetchImages()
 }, [])

   // API endpoint
   const endpoint = “<Endpoint here once available>”

   // Fetch Images from functions
 const fetchImages = () => {
   axios(endpoint).then(res => {
     setImages([…images, …res.data.images])
     setLoading(false)
   })
 }
 return (
   <ImageGallery images={images} loading={loading} fetchImages={fetchImages} />
 )
}

Here, we created state variables to hold the fetched images and also to store the state of the fetch operation. The images variable defaults to an empty array while the loading variable defaults to true as we assume by default, the images are loading once the component mounts.

The useEffect hook is used to call the fetchImages function once the component is mounted. An empty array as a second argument signifies that the function will only run when the component mounts.

A fetchImages function is created which uses axios to make a GET request to a specified API. The returned data is spread in the images array in state. Thus any new data fetched is added to existing ones in state. The loading variable is also set to false as the fetch operation is complete.

The ImageGallery component earlier created is used to render the gallery with the required data.

Assign the Proptypes to the ImageGallery component and export the InfiniteImage module with:

import…

const ImageGallery = ({ images, loading, fetchImages }) => {
 // Create gallery here
 return (
   // Component logic here
 )
}

const InfiniteImages = () => {
 // Component logic here
}

ImageGallery.propTypes = {
 images: PropTypes.array,
 loading: PropTypes.bool,
 fetchImages: PropTypes.func,
}

export default InfiniteImages

With this, we have the gallery set up, what’s missing is the API endpoint. We’ll proceed to define a Netlify function to handle that.

Create The Netlify Function

Netlify functions are AWS lambdas managed directly on Netlify. With this, we abstract the management and scaling of a traditional server. Multiple functions can be created and used across an application after the application is built.

These functions in JavaScript are .js files stored in any designated directory in the project’s repository and specified on Netlify or in the netlify.toml config file in the root directory of a project.

Creating a Netlify function is seamless. It is either created in a functions directory or a build tool is used to create the function from a source folder into the functions folder.

If you are familiar with backend development, creating node servers and APIs would probably be a breeze, for Netlify Functions written in JavaScript, knowledge of Nodejs is not compulsory as Netlify ships Netlify-lambda. This is a tool to help with building Netlify functions from modern JavaScript workflows using webpack/babel.

We will employ this in this tutorial to build functions written in ES6 syntax into a functions directory.

For this gallery, we will query a free Unsplash API to obtain super cute images of dogs and display them in a masonry. Head to Unsplash, signup to create a new app and get an access key.

While this API can be consumed directly in the app, we would like to abstract this image fetching process to our API, thus securing access/private keys or any other backend logic. In other applications, business or other logic can also go in our API.

Install Functions Build tool

netlify-lambda CLI is used to run functions locally as well as create a deployable build. These functions can be written with modern JS workflows before being bundled into a single build using webpack/babel. For this project, we’ll create a folder to house the locally written functions as well as the deployable functions. 

Install the netlify-lambda CLI with:

npm i -g netlify-lambda

With this we can serve the functions locally with:

netlify-lambda serve <path-to-source-folder>

A deployable build can be created with :

netlify-lambda build <path-to-source-folder>

Create a Function and Source Directory

Create a folder in the src directory named lambda. This serves as the source folder will contain all the functions as written. Create a second folder in the root directory of the project named functions. This, in turn, will hold all deployable functions. For Netlify to recognize the functions folder, we need to specify it in the Netlify config file. Create a file in the root directory of the project named netlify.toml. Add this config with:

[build]
 Functions = “functions”

This specifies that the functions for the app can be found in the functions directory in the app root. Once this app is deployed, each function will be available on:

https://<root-url-of-app>/.netlify/functions/<function-name>

Define The Fetch Function

Lambda functions are JS files which export a handler method. Each function takes three parameters:

  • event: This is an object received when the function is triggered.
  • context: This contains the conditions in which the function was called.
  • callback: This is returned on function execution and contains the error if any, as the first parameter. It also contains a response payload as the second.

In the project, create a file named fetch.js in src/lambda, configure the function with:

import axios from “axios”
import config from “…/…/config”

exports.handler = function(event, context, callback) {
 const apiRoot = “https://api.unsplash.com
 const accessKey = process.env.ACCESS_KEY || config.accessKey

 const doggoEndpoint = ${apiRoot}/photos/random?client_id=${accessKey}&amp;count=${10}&amp;collections='3816141,1154337,1254279'

 axios.get(doggoEndpoint).then(res => {
   callback(null, {
     statusCode: 200,
     body: JSON.stringify({
       images: res.data,
     }),
   })
 })
}

In here, axios which is imported is used to make an API call to the Unsplash API, and the returned data is sent in the callback with a status code of 200. The API Key will be stored as an environment variable on Netlify and also in a config file for local usage.

Create a file named config.js in the root directory and add the API key from Unsplash with:

const config = {
 accessKey: “<Add access key>”,
}

export default config

Be sure to add the config file to .gitignore so it’s not added to your repository if public.

State a dev server for the functions with:

netlify-lambda serve src/lambda

This creates a server on http://localhost:9000.

Navigate to http://localhost:9000/fetch to see the data fetched from the API being displayed on the browser. 

To create a build in the functions folder, run:

netlify-lambda build src/lambda

This creates a build in the functions folder ready to be deployed.

We have the functions set up and running, let’s configure it for local usage.

Configure Function for Local Usage

Using the function as is in the local dev server on Gatsby would throw a CORS error. Advanced proxying in Gatsby.js, affords us the ability to use a proxy middleware to proxy the functions in our local environment consequently bypassing CORS. Install http-proxy-middleware with:

npm i --save-dev http-proxy-middleware

Configure the proxy middleware in gatsby-config.js with:

let proxy = require(“http-proxy-middleware”)

module.exports = {
 siteMetadata: {
   // define site metadata
 },
 // Enables the use of function URLs locally
 developMiddleware: app => {
   app.use(
     “/.netlify/functions/”,
     proxy({
       target: “http://localhost:9000”,
       pathRewrite: { “/.netlify/functions/”: “” },
     })
   )
 },
 plugins: [
   // define plugins
 ],
}

The /.netlify/functions/ endpoint in development is proxied to http://local:9000 and the path is re-written, this way http://localhost:9000/fetch becomes /.netlify/functions/fetch which is also the valid local endpoint for the function.

Pass the API endpoint to the axios request in the InfiniteImages function in src/components/InfiniteImages.js. Do this with:

import // …

const ImageGallery = ({ images, loading, fetchImages }) => {
 // Component logic here
}

const InfiniteImages = () => {
 // Hold state
 const [images, setImages] = useState([])
 const [loading, setLoading] = useState(true)

 // Fetch images on component mount
 useEffect(() => {
   fetchImages()
 }, [])

 // Fetch Images from functions
 const fetchImages = () => {
   axios(“/.netlify/functions/fetch”).then(res => {
     setImages([…images, …res.data.images])
     setLoading(false)
   })
 }
 return (
   <ImageGallery images={images} loading={loading} fetchImages={fetchImages} />
 )
}

ImageGallery.propTypes = {
   // Define proptypes
}

export default InfiniteImages

Restart the Gatsby dev server, while ensuring the server of the local function is running. Here’s what the app looks now:

Deploying to Netlify

At this point, the app works on our local environment. Before deploying to Netlify, re-build the functions with:

netlify-lambda build src/lambda

Run a Gatsby build to verify the build process works without errors. Do this with:

gatsby build

Next is to deploy to a Git provider.

Push to Git Provider

Create a new repository on a remote git provider. Initialize the repository on your local machine, stage all your files, commit and push to the new remote repository.

Ensure the config.js file in the root directory is added to .gitignore.

Deploy On Netlify

Go on to Netlify and create an account. Use the “New site from Git” button to add a new site.

On the “Connect to Git Provider” tab, select GitHub or whichever provider you used and authorize your account. In the next tab, pick the repository you deployed to or use the search function to search for the repository.

Configure the deploy settings with the build command as gatsby build and publish directory as public. Click the “Show advanced” button then the “new variable” button to add a new environment variable.

Hit the “Deploy site” button to deploy.

Netlify deploys the site and utilizes the functions in the functions directory after build. These functions are not exposed on the client side except the functions directory is in the publish directory.

Note that the build command, publish directory and environment variables can also be set in the netlify.toml file of the project.

You can find the final deployed site at https://gastify.netlify.com

You can find the repository here: https://github.com/Chuloo/gatsby-netlify-functions

Here’s a peek on lighthouse audit scores of the deployed site:

Conclusion

In this post, we saw an overview of static sites, their features, importance, going dynamic with fetching dynamic content using serverless functions and an overview of serverless functions.




#web-development #javascript #node-js #reactjs #graphql

PANDAS: Most Used Functions in Data Science

Most useful functions for data preprocessing

When you get introduced to machine learning, the first step is to learn Python and the basic step of learning Python is to learn pandas library. We can install pandas library by pip install pandas. After installing we have to import pandas each time of the running session. The data used for example is from the UCI repository “https://archive.ics.uci.edu/ml/datasets/Heart+failure+clinical+records

  1. Read Data

2. Head and Tail

3. Shape, Size and Info

4. isna

#pandas: most used functions in data science #pandas #data science #function #used python data #most used functions in data science

Why Use WordPress? What Can You Do With WordPress?

Can you use WordPress for anything other than blogging? To your surprise, yes. WordPress is more than just a blogging tool, and it has helped thousands of websites and web applications to thrive. The use of WordPress powers around 40% of online projects, and today in our blog, we would visit some amazing uses of WordPress other than blogging.
What Is The Use Of WordPress?

WordPress is the most popular website platform in the world. It is the first choice of businesses that want to set a feature-rich and dynamic Content Management System. So, if you ask what WordPress is used for, the answer is – everything. It is a super-flexible, feature-rich and secure platform that offers everything to build unique websites and applications. Let’s start knowing them:

1. Multiple Websites Under A Single Installation
WordPress Multisite allows you to develop multiple sites from a single WordPress installation. You can download WordPress and start building websites you want to launch under a single server. Literally speaking, you can handle hundreds of sites from one single dashboard, which now needs applause.
It is a highly efficient platform that allows you to easily run several websites under the same login credentials. One of the best things about WordPress is the themes it has to offer. You can simply download them and plugin for various sites and save space on sites without losing their speed.

2. WordPress Social Network
WordPress can be used for high-end projects such as Social Media Network. If you don’t have the money and patience to hire a coder and invest months in building a feature-rich social media site, go for WordPress. It is one of the most amazing uses of WordPress. Its stunning CMS is unbeatable. And you can build sites as good as Facebook or Reddit etc. It can just make the process a lot easier.
To set up a social media network, you would have to download a WordPress Plugin called BuddyPress. It would allow you to connect a community page with ease and would provide all the necessary features of a community or social media. It has direct messaging, activity stream, user groups, extended profiles, and so much more. You just have to download and configure it.
If BuddyPress doesn’t meet all your needs, don’t give up on your dreams. You can try out WP Symposium or PeepSo. There are also several themes you can use to build a social network.

3. Create A Forum For Your Brand’s Community
Communities are very important for your business. They help you stay in constant connection with your users and consumers. And allow you to turn them into a loyal customer base. Meanwhile, there are many good technologies that can be used for building a community page – the good old WordPress is still the best.
It is the best community development technology. If you want to build your online community, you need to consider all the amazing features you get with WordPress. Plugins such as BB Press is an open-source, template-driven PHP/ MySQL forum software. It is very simple and doesn’t hamper the experience of the website.
Other tools such as wpFoRo and Asgaros Forum are equally good for creating a community blog. They are lightweight tools that are easy to manage and integrate with your WordPress site easily. However, there is only one tiny problem; you need to have some technical knowledge to build a WordPress Community blog page.

4. Shortcodes
Since we gave you a problem in the previous section, we would also give you a perfect solution for it. You might not know to code, but you have shortcodes. Shortcodes help you execute functions without having to code. It is an easy way to build an amazing website, add new features, customize plugins easily. They are short lines of code, and rather than memorizing multiple lines; you can have zero technical knowledge and start building a feature-rich website or application.
There are also plugins like Shortcoder, Shortcodes Ultimate, and the Basics available on WordPress that can be used, and you would not even have to remember the shortcodes.

5. Build Online Stores
If you still think about why to use WordPress, use it to build an online store. You can start selling your goods online and start selling. It is an affordable technology that helps you build a feature-rich eCommerce store with WordPress.
WooCommerce is an extension of WordPress and is one of the most used eCommerce solutions. WooCommerce holds a 28% share of the global market and is one of the best ways to set up an online store. It allows you to build user-friendly and professional online stores and has thousands of free and paid extensions. Moreover as an open-source platform, and you don’t have to pay for the license.
Apart from WooCommerce, there are Easy Digital Downloads, iThemes Exchange, Shopify eCommerce plugin, and so much more available.

6. Security Features
WordPress takes security very seriously. It offers tons of external solutions that help you in safeguarding your WordPress site. While there is no way to ensure 100% security, it provides regular updates with security patches and provides several plugins to help with backups, two-factor authorization, and more.
By choosing hosting providers like WP Engine, you can improve the security of the website. It helps in threat detection, manage patching and updates, and internal security audits for the customers, and so much more.

Read More

#use of wordpress #use wordpress for business website #use wordpress for website #what is use of wordpress #why use wordpress #why use wordpress to build a website

Dedrick  Bednar

Dedrick Bednar

1595220720

Enabling E-Commerce Quickly with Gatsby & Netlify Functions

Gatsby has become widely popular.

And rightly so. It’s a compelling tool to craft fast static websites, web apps, or PWAs.

As we’re witness to its rising adoption, it’s always thrilling for us when developers reach out to show off their new Gatsby e-commerce projects featuring Snipcart.

Devs like Patrick Faramaz who came up with a cool mix of Gatsby, Snipcart & Netlify Functions for his client’s online store.

We were instantly intrigued and asked him to answer a few questions about his stack, which he gladly accepted :)

Not only this, but Patrick also crafted and shared a Gatsby e-commerce plugin. We’ll also talk about it at the end of this article.

Let’s see what he had to say about Gatsby, Jamstack & e-commerce!

The developer we’re interviewing

Patrick Faramaz has been a web developer for twelve years now. He’s had many work experiences in the field before switching to independent work four years ago. He builds websites & apps primarily for clients in France, his home country, and Swiss. You can find more info about his services on his website (in French).

Patrick has been a full stack developer since the beginning but has kept more of a focus on React in the last five years. This popular JavaScript framework allows him to craft websites with modern & performant UIs enabling top-notch user experiences.

We’ll see an example of that right away!

For French-speakers, Patrick already talked about his experience with Gatsby & Snipcart on this podcast and wrote about it in this blog post.

The client

mercredi-biscuiterie-website

Mercredi Biscuiterie is a bakery based in Lyon, France. Like many shops around the world, they found themselves in a tricky situation when they were forced to suddenly close its physical shop due to Covid-19 hitting their country.

The situation was particularly hard for small businesses such as Mercredi Biscuiterie that thought of eventually selling online but had no system in place to do so yet. They had to react quickly. After a month of the bakery being closed, they turned to Patrick to come up with a solution to start selling online.

We’ve heard many similar stories in the last few months. It’s a very tough situation for merchants right now, sadly. We like to think we’ve been able to help small businesses get through this in allowing them to enable e-commerce quickly.

Let’s see how Patrick did it for Mercredi Biscuiterie.

#gatsby #netlify #functions