jamstack-ecommerce-example
JAMStack E-Commerce Example
This is a showcase of an e-commerce website built with the
JAMStack using Nuxt.js as the web
application framework and Salesforce as the data
storage for products and orders as well as for user authentication.
-
JAMStack E-Commerce Example
- Example Features
- JAMStack Architecture
-
Running the Showcase
<li> <a rel="nofollow noopener" target="_blank" href="#running-the-content-update-script">Running the Content Update Script</a> </li> <li> <a rel="nofollow noopener" target="_blank" href="#running-the-api-server">Running the API Server</a> </li> <li> <a rel="nofollow noopener" target="_blank" href="#running-the-web-application">Running the Web Application</a> </li> </ul> </li> <li> <a rel="nofollow noopener" target="_blank" href="#license">License</a> </li> </ul>
-
Pre-Generated Static HTML Files: All pages that make up the website are
pre-generated at build time. This even includes one product detail page for
each product. These static HTML files can be served by any web server or
Content Delivery Network (CDN). -
Pre-fetched Product Content: Content for products is pre-fetched from
Salesforce using a dedicated Node.js script. This script should be executed
before the static HTML files are generated. It fetches product data via the
Salesforce REST API and stores the content locally as JSON files. They can be
committed to the Git repository and are used to generate the HTML files. -
Authentication via Salesforce: Visitors can authenticate with their
Salesforce customer community user via the OpenID Connect protocol. This
requires only a minimal Lightning Community configuration and a Connected App
in Salesforce. -
Individual User Content: Once logged in the website visitors can view
their own user profile which displays their Account data from Salesforce. This
data is fetched via the little API server so that visitors do not communicate
directly with the Salesforce REST API. -
Client-Side Shopping Cart: All items added to the shopping cart are stored
client-side in the browser’s local storage. No server communication required.
Visitors can still close the browser and have their cart content restored when
accessing the page again (with the same browser on the same device). -
Order Transmission to Salesforce: Logged in visitors can place orders by
sending their shopping cart to the API server. This server transforms the cart
data into a proper Salesforce order and transmits the records via the
Salesforce REST API. -
Delegated Logout via Salesforce: When logging out on the website visitors
can be redirected to a special logout page in the Lightning Community to log
them out there as well and then return to the website.
Since the pages accessed by the website visitors are not generated dynamically
when they are requested but pre-generated and served as static HTML files, the
process of rolling out new features and content looks a little bit different
than in “traditional” web applications.-
Local Development: Development of new features can be done locally.
Nuxt.js comes with very effective tools to support a great developer
experience like a dev server with hot module replacement and live reload.
Content for products is stored in the Git repository alongside with the
source code, so developers can make use of real product data during
implementation and testing.
API endpoints should be stubbed using some mock server, e.g.
WireMock or
mockserver, in order to work
independently from real external systems. For OpenID Connect authentication
consider setting up KeyCloak locally.
Note: This example project does not include any mock server. -
Pre-Fetching Content: Everytime new or updated product data has to be
published on the website the pre-fetched content JSON files must be updated
in the Git repository before a new version of static HTML files is generated.
The special Node.js content script will connect to Salesforce and fetch the
most recent data via the Salesforce REST API. The content JSON files are
updated accordingly and can be committed to the Git repository.
It is completely up to you where and when this script is executed. For
example, it can run as a GitHub Action
or in a CI process on Travis CI.
Note: Salesforce is just an example of a potential data source to acquire
content from. Content files can also be created from any other data source. -
Publishing Static HTML Files: Every commit in the Git repository
represents a certain implementation and content state of the website which
can potentially be published.
The build process transforms the source code into optimized chunks and
generates the static HTML files by computing all accessible routes for the
implemented page components and the pre-fetched content files.
Finally, all generated website files can be published to any web server or
Content Delivery Network, e.g. Netlify.
Note: The build process can also leverage API requests to load content which
is not stored in content files in the Git repository. -
Dynamic Enhancement via APIs: Visitors are served static HTML files when
loading the website in the browser. This is extremely fast because nothing
needs dynamically generated on the server.
Once the web page has loaded the dynamic JavaScript kicks in and enhances the
page with dynamic features. This can be features like the shopping cart or
displaying personalized user content.
Dynamic data can be fetched by sending API requests from the browser.
Visitors can authenticate using standard protocols like OAuth 2.0 and OpenID
Connect to allow the website to present individual content.
- Node.js 12.x or higher
- Yarn package manager
-
Salesforce organization, e.g free
Developer Edition
Why? It enables the login with a real customer user in the Lightning Community.
-
Open Salesforce Setup and navigate to “Communities”. Make sure that
communities are enabled. - In the Salesforce Setup navigate to “Profiles”.
-
Clone the profile “Customer Community User” to create a custom profile
specifically for users of the new community. For example, call it “Example
Customer User”. -
Open the Sales Cloud to create an Account and Contact for testing purposes.
On the Contact view select the quick action “Enable Customer User”.- Set the “User License” to “Customer Community”.
- Assign the profile created in the previous step.
-
Enter your own e-mail address to receive the welcome e-mail message once
the user is added as member to the community.
This step is required if you are planning to use the content update script and
if you want to set up automatic logout in the Lightning Community when users log
out in the website.
Why? It adds the custom object “Product Category” to your Salesforce org and
installs a custom field on the Product2 object to let you define the category a
product belongs to. It also installs a Lightning Web Component to be used on a
special logout community page which will automatically log the user out.-
Download and install
Salesforce CLI. -
Open a terminal in the directory
salesforce
. -
Connect Salesforce CLI to your Salesforce org.
sfdx force:auth:web:login -a MyOrg -s
-
Deploy the SFDX project to your Salesforce org.
sfdx force:source:deploy -p force-app
Why? It allows the API server and content script to connect to Salesforce with a
specific technical user which allows for individual access control.- Open Salesforce Setup and navigate to “Users”.
-
Create a new user.
- Set the “User License” to “Salesforce”
- Assign the profile “System Administrator”.
- Give the user some name like “Integration”.
- Enter your own e-mail address in order to receive the registration e-mail.
-
If you are planning to use the content update script please assign the
permission set “Product Category Editor” to the integration user. -
Confirm the verification e-mail and complete the user registration by
entering a new password. - Log in to Salesforce with that integration user.
- In the user menu next to the Setup icon select “Settings”.
-
Navigate to “Reset My Security Token” and click the button “Reset Security
Token”. You should receive the new token via e-mail.
Why? It is required to display the login page during the OpenID Connect
authentication flow.- Open Salesforce Setup and navigate to “All Communities”.
-
Click the button “New Community” and choose the template “Build Your Own”.
Give it some arbitrary name and preferrably leave the URL blank. - Open the “Workspace” of the new community and go to “Administration”.
- In the “Settings” section activate the community.
-
Temporarily switch back to Salesforce Setup at “All Communities” and open the
“Builder” of the new community. Click the “Publish” button. -
Back in the “Workspace” of the community go to the “Emails” section and enter
your own e-mail address in the “Sender” configuration. Make sure to confirm
the e-mail message which is sent to you. - Activate the checkbox “Send welcome email”.
-
In the “Members” section assign the profile previously created for customer
community users (e.g. “Example Customer User”). You should receive a welcome
e-mail message for the test user created before. Complete the user
registration by entering a new password.
If you want to set up automatic logout for community users when they log out on
the website perform these additional steps:- Open the “Workspace” of the community and go to “Administration”.
-
In the “Login & Registration” section enter the website’s logout URL in the
“Logout Page URL” field (e.g. if running the website on
http://localhost:3000 enter the URL http://localhost:3000/logout) -
Switch back to Salesforce Setup at “All Communities” and open the “Builder”
of the community. -
Create a blank standard page with an arbitrary content layout (e.g. “1
full-width column”). Give the page the name “Logout” and the URL “logout”. - In the page settings set “Page Access” to “Requires Login”.
-
Drag the custom component “JSEC Auto Logout” from the “Components” panel to
the content region of the page. Do not be confused: This will immediately
redirect you to an error page in Experience Builder because that component
attempts to log the user out when rendered. This is just an indicator that
the component works as expected. - Publish the changes made to the community.
Why? It is required for the OpenID Connect authentication for website visitors
and allows the API server and content script to connect to Salesforce in a
secure way.- Open Salesforce Setup and navigate to the “App Manager”.
-
Click the button “New Connected App” and enter the following data.
- Connected App Name: (Choose anything you like, e.g. “Local OIDC”)
- API Name: (Choose anything you like, e.g. “Local_OIDC”)
- Contact Email: (Your e-mail address)
- Enable OAuth Setting: Activated
- Callback URL: http://localhost:3000/login/callback
-
Selected OAuth Scoped:
- Access your basic information (id, profile, email, address, phone)
- Allow access to your unique identifier (openid)
-
Perform requests on your behalf at any time (refresh_token,
offline_access)
<li> Require Secret for Web Server Flow: Deactivated </li> <li> Configure ID Token: Activated </li> <li> Token Valid for: (some reasonable session lifetime, e.g. 240 minutes) </li> <li> ID Token Audiences: (leave empty, meaning consumer key is used) </li> <li> Include Standard Claims: Activated </li> </ul>
-
From the Connected App View copy the “Consumer Key” and the “Consumer Secret”
for later use in configuration parameters. - Click the button “Manage” and then “Edit Policies”.
- Set the “Permitted Users” field to “Admin approved users are pre-authorized”.
-
In the “Profiles” panel click the button “Manage Profiles” and assign both
the profile previously created for customer community users (e.g. “Example
Customer User”) and the profile for the integration user (e.g. “System
Administrator”).
This step is optional because the Git repository already contains some example
products and categories for demonstration.
You should have some records for the Product2…