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.
Why? It enables the login with a real customer user in the Lightning 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.
Why? It is required to display the login page during the OpenID Connect authentication flow.
If you want to set up automatic logout for community users when they log out on the website perform these additional steps:
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.
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 object in your Salesforce org which are active and have Price Book Entries in some Price Book used for the content update.
You may also create some Product Categories and assign them to your products.
Note: The script requires the Salesforce metadata to be deployed in your org.
Open a terminal in the directory content-scripts
.
Set the following environment variables.
Name | Description |
---|---|
SALESFORCE_INSTANCE_URL | Base URL of the Salesforce instance (pattern https://xx##.salesforce.com ) |
SALESFORCE_API_VERSION | Salesforce API version to use |
SALESFORCE_TOKEN_ENDPOINT | OAuth 2.0 token endpoint of the Salesforce instance |
SALESFORCE_CLIENT_ID | Consumer Key of the Connected App (copied before from App view) |
SALESFORCE_CLIENT_SECRET | Consumer Secret of the Connected App (copied before from App view) |
SALESFORCE_USERNAME | Username of the integration user |
SALESFORCE_PASSWORD | Password of the integration user + security token (simply concatenate the two) |
SALESFORCE_PRICE_BOOK_NAME | Optional. Price book to use. Default: "Standard Price Book" |
Example:
SALESFORCE_INSTANCE_URL=https://eu25.salesforce.com
SALESFORCE_API_VERSION=49.0
SALESFORCE_TOKEN_ENDPOINT=https://login.salesforce.com/services/oauth2/token
SALESFORCE_CLIENT_ID=3MVG9...ru7XA
SALESFORCE_CLIENT_SECRET=17DAD...0110F
[email protected]
SALESFORCE_PASSWORD=abcde...KiQ9n
Tip: You can put these variable assignments in a file called .env
in the
directory content-scripts
for development and testing.
Install the Node.js dependencies.
yarn install
Run the script to update the categories and products JSON files in the
directory content
.
yarn start
Open a terminal in the directory api
.
Set the following environment variables.
Name | Description |
---|---|
PORT | Local server port to listen on. Default: 3000 |
SALESFORCE_INSTANCE_URL | Base URL of the Salesforce instance (pattern https://xx##.salesforce.com ) |
SALESFORCE_API_VERSION | Salesforce API version to use |
SALESFORCE_TOKEN_ENDPOINT | OAuth 2.0 token endpoint of the Salesforce instance (not community) |
SALESFORCE_JWKS_ENDPOINT | OpenID Connect JSON Web Key Set endpoint of the Salesforce Lightning Community |
SALESFORCE_ISSUER_URL | Issuer URL included in the ID token issued by Salesforce |
SALESFORCE_CLIENT_ID | Consumer Key of the Connected App (copied before from App view) |
SALESFORCE_CLIENT_SECRET | Consumer Secret of the Connected App (copied before from App view) |
SALESFORCE_USERNAME | Username of the integration user |
SALESFORCE_PASSWORD | Password of the integration user + security token (simply concat the two) |
SALESFORCE_PRICE_BOOK_NAME | Optional. Price book to use. Default: "Standard Price Book" |
SECURITY_CORS_ORIGIN | Base URL of the web application allowed to access the server. |
Example:
PORT=4000
SALESFORCE_INSTANCE_URL=https://eu25.salesforce.com
SALESFORCE_API_VERSION=49.0
SALESFORCE_TOKEN_ENDPOINT=https://login.salesforce.com/services/oauth2/token
SALESFORCE_JWKS_ENDPOINT=https://georgwittberger-developer-edition.eu25.force.com/id/keys
SALESFORCE_ISSUER_URL=https://georgwittberger-developer-edition.eu25.force.com
SALESFORCE_CLIENT_ID=3MVG9...ru7XA
SALESFORCE_CLIENT_SECRET=17DAD...0110F
[email protected]
SALESFORCE_PASSWORD=abcde...KiQ9n
SECURITY_CORS_ORIGIN=http://localhost:3000
Tip: You can put these variable assignments in a file called .env
in the
directory api
for development and testing.
Install the Node.js dependencies.
yarn install
Run the server.
yarn start
Open a terminal in the project root directory.
Set the following environment variables.
Name | Description |
---|---|
API_URL | Base URL of the API server |
LOGOUT_URL | Optional. Logout page URL of the Salesforce Lightning Community |
OAUTH2_AUTHORIZE_ENDPOINT | OAuth 2.0 authorization endpoint of the Salesforce Lightning Community |
OAUTH2_USERINFO_ENDPOINT | User info endpoint of the API server |
OAUTH2_CLIENT_ID | Consumer Key of the Connected App (copied before from App view) |
OAUTH2_SCOPES | OAuth 2.0 scopes to request during authentication, comma-separated |
Example:
API_URL=http://localhost:4000
LOGOUT_URL=https://georgwittberger-developer-edition.eu25.force.com/s/logout
OAUTH2_AUTHORIZE_ENDPOINT=https://georgwittberger-developer-edition.eu25.force.com/services/oauth2/authorize
OAUTH2_USERINFO_ENDPOINT=http://localhost:4000/userinfo
OAUTH2_CLIENT_ID=3MVG9...ru7XA
OAUTH2_SCOPES=openid,id
Tip: You can put these variable assignments in a file called .env
in the
project root directory for development and testing.
Note: If the variable LOGOUT_URL
is not provided users will be redirected
to the website's logout page immediately without external roundtrip.
Install the Node.js dependencies.
yarn install
Either launch the development server which offers live reload ...
yarn dev
... or generate the static HTML files first and then serve these files from
the dist
directory.
yarn generate
yarn start
Open your browser on http://localhost:3000
MIT License