From aa2ca6c534360c588df5c9a71a713e2a8befdc18 Mon Sep 17 00:00:00 2001 From: Byron Matto Date: Tue, 24 Sep 2024 09:00:57 -0400 Subject: [PATCH 1/6] Example now in "Unified" style --- .../getting-started-app/cms-assets.json | 4 ---- .../{getting-started-project => }/hsproject.json | 2 +- examples/getting-started/package.json | 2 +- .../getting-started-theme}/Globals.d.ts | 0 .../getting-started-theme}/assets/clear.svg | 0 .../getting-started-theme}/assets/cloudy.svg | 0 .../getting-started-theme}/assets/fog.svg | 0 .../getting-started-theme}/assets/rain.svg | 0 .../getting-started-theme}/assets/snow.svg | 0 .../getting-started-theme}/assets/sprocket.svg | 0 .../getting-started-theme}/assets/thunderstorm.svg | 0 .../getting-started-theme}/components/WeatherCards.tsx | 0 .../components/islands/WeatherForecast.tsx | 0 .../components/modules/Footer/index.tsx | 0 .../components/modules/Header/index.tsx | 0 .../components/modules/Weather/index.tsx | 0 .../getting-started-theme}/constants.ts | 0 .../{ => src}/getting-started-theme/fields.json | 0 .../{ => src}/getting-started-theme/layouts/base.hubl.html | 4 ++-- .../getting-started-theme}/package.json | 0 .../getting-started-theme}/styles/footer.module.css | 0 .../getting-started-theme}/styles/header.module.css | 0 .../getting-started-theme}/styles/weather.module.css | 0 .../{ => src}/getting-started-theme/theme.json | 0 .../getting-started-theme}/tsconfig.json | 0 .../getting-started-theme}/utils.ts | 0 .../{ => src}/getting-started-theme/weather.hubl.html | 2 +- 27 files changed, 5 insertions(+), 9 deletions(-) delete mode 100644 examples/getting-started/getting-started-project/getting-started-app/cms-assets.json rename examples/getting-started/{getting-started-project => }/hsproject.json (78%) rename examples/getting-started/{getting-started-project/getting-started-app => src/getting-started-theme}/Globals.d.ts (100%) rename examples/getting-started/{getting-started-project/getting-started-app => src/getting-started-theme}/assets/clear.svg (100%) rename examples/getting-started/{getting-started-project/getting-started-app => src/getting-started-theme}/assets/cloudy.svg (100%) rename examples/getting-started/{getting-started-project/getting-started-app => src/getting-started-theme}/assets/fog.svg (100%) rename examples/getting-started/{getting-started-project/getting-started-app => src/getting-started-theme}/assets/rain.svg (100%) rename examples/getting-started/{getting-started-project/getting-started-app => src/getting-started-theme}/assets/snow.svg (100%) rename examples/getting-started/{getting-started-project/getting-started-app => src/getting-started-theme}/assets/sprocket.svg (100%) rename examples/getting-started/{getting-started-project/getting-started-app => src/getting-started-theme}/assets/thunderstorm.svg (100%) rename examples/getting-started/{getting-started-project/getting-started-app => src/getting-started-theme}/components/WeatherCards.tsx (100%) rename examples/getting-started/{getting-started-project/getting-started-app => src/getting-started-theme}/components/islands/WeatherForecast.tsx (100%) rename examples/getting-started/{getting-started-project/getting-started-app => src/getting-started-theme}/components/modules/Footer/index.tsx (100%) rename examples/getting-started/{getting-started-project/getting-started-app => src/getting-started-theme}/components/modules/Header/index.tsx (100%) rename examples/getting-started/{getting-started-project/getting-started-app => src/getting-started-theme}/components/modules/Weather/index.tsx (100%) rename examples/getting-started/{getting-started-project/getting-started-app => src/getting-started-theme}/constants.ts (100%) rename examples/getting-started/{ => src}/getting-started-theme/fields.json (100%) rename examples/getting-started/{ => src}/getting-started-theme/layouts/base.hubl.html (92%) rename examples/getting-started/{getting-started-project/getting-started-app => src/getting-started-theme}/package.json (100%) rename examples/getting-started/{getting-started-project/getting-started-app => src/getting-started-theme}/styles/footer.module.css (100%) rename examples/getting-started/{getting-started-project/getting-started-app => src/getting-started-theme}/styles/header.module.css (100%) rename examples/getting-started/{getting-started-project/getting-started-app => src/getting-started-theme}/styles/weather.module.css (100%) rename examples/getting-started/{ => src}/getting-started-theme/theme.json (100%) rename examples/getting-started/{getting-started-project/getting-started-app => src/getting-started-theme}/tsconfig.json (100%) rename examples/getting-started/{getting-started-project/getting-started-app => src/getting-started-theme}/utils.ts (100%) rename examples/getting-started/{ => src}/getting-started-theme/weather.hubl.html (69%) diff --git a/examples/getting-started/getting-started-project/getting-started-app/cms-assets.json b/examples/getting-started/getting-started-project/getting-started-app/cms-assets.json deleted file mode 100644 index f7037b1..0000000 --- a/examples/getting-started/getting-started-project/getting-started-app/cms-assets.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Getting started", - "outputPath": "" -} diff --git a/examples/getting-started/getting-started-project/hsproject.json b/examples/getting-started/hsproject.json similarity index 78% rename from examples/getting-started/getting-started-project/hsproject.json rename to examples/getting-started/hsproject.json index 7de2a73..f38bacf 100644 --- a/examples/getting-started/getting-started-project/hsproject.json +++ b/examples/getting-started/hsproject.json @@ -1,5 +1,5 @@ { "name": "getting-started-project", - "srcDir": ".", + "srcDir": "src", "platformVersion": "2023.2" } diff --git a/examples/getting-started/package.json b/examples/getting-started/package.json index 59c2455..9365759 100644 --- a/examples/getting-started/package.json +++ b/examples/getting-started/package.json @@ -18,7 +18,7 @@ "prettier": "prettier . --check", "watch:hubl": "hs watch getting-started-theme getting-started-theme", "upload:hubl": "hs upload getting-started-theme getting-started-theme", - "deploy": "hs project upload getting-started-project" + "deploy": "hs project upload ." }, "engines": { "node": ">=16.0.0" diff --git a/examples/getting-started/getting-started-project/getting-started-app/Globals.d.ts b/examples/getting-started/src/getting-started-theme/Globals.d.ts similarity index 100% rename from examples/getting-started/getting-started-project/getting-started-app/Globals.d.ts rename to examples/getting-started/src/getting-started-theme/Globals.d.ts diff --git a/examples/getting-started/getting-started-project/getting-started-app/assets/clear.svg b/examples/getting-started/src/getting-started-theme/assets/clear.svg similarity index 100% rename from examples/getting-started/getting-started-project/getting-started-app/assets/clear.svg rename to examples/getting-started/src/getting-started-theme/assets/clear.svg diff --git a/examples/getting-started/getting-started-project/getting-started-app/assets/cloudy.svg b/examples/getting-started/src/getting-started-theme/assets/cloudy.svg similarity index 100% rename from examples/getting-started/getting-started-project/getting-started-app/assets/cloudy.svg rename to examples/getting-started/src/getting-started-theme/assets/cloudy.svg diff --git a/examples/getting-started/getting-started-project/getting-started-app/assets/fog.svg b/examples/getting-started/src/getting-started-theme/assets/fog.svg similarity index 100% rename from examples/getting-started/getting-started-project/getting-started-app/assets/fog.svg rename to examples/getting-started/src/getting-started-theme/assets/fog.svg diff --git a/examples/getting-started/getting-started-project/getting-started-app/assets/rain.svg b/examples/getting-started/src/getting-started-theme/assets/rain.svg similarity index 100% rename from examples/getting-started/getting-started-project/getting-started-app/assets/rain.svg rename to examples/getting-started/src/getting-started-theme/assets/rain.svg diff --git a/examples/getting-started/getting-started-project/getting-started-app/assets/snow.svg b/examples/getting-started/src/getting-started-theme/assets/snow.svg similarity index 100% rename from examples/getting-started/getting-started-project/getting-started-app/assets/snow.svg rename to examples/getting-started/src/getting-started-theme/assets/snow.svg diff --git a/examples/getting-started/getting-started-project/getting-started-app/assets/sprocket.svg b/examples/getting-started/src/getting-started-theme/assets/sprocket.svg similarity index 100% rename from examples/getting-started/getting-started-project/getting-started-app/assets/sprocket.svg rename to examples/getting-started/src/getting-started-theme/assets/sprocket.svg diff --git a/examples/getting-started/getting-started-project/getting-started-app/assets/thunderstorm.svg b/examples/getting-started/src/getting-started-theme/assets/thunderstorm.svg similarity index 100% rename from examples/getting-started/getting-started-project/getting-started-app/assets/thunderstorm.svg rename to examples/getting-started/src/getting-started-theme/assets/thunderstorm.svg diff --git a/examples/getting-started/getting-started-project/getting-started-app/components/WeatherCards.tsx b/examples/getting-started/src/getting-started-theme/components/WeatherCards.tsx similarity index 100% rename from examples/getting-started/getting-started-project/getting-started-app/components/WeatherCards.tsx rename to examples/getting-started/src/getting-started-theme/components/WeatherCards.tsx diff --git a/examples/getting-started/getting-started-project/getting-started-app/components/islands/WeatherForecast.tsx b/examples/getting-started/src/getting-started-theme/components/islands/WeatherForecast.tsx similarity index 100% rename from examples/getting-started/getting-started-project/getting-started-app/components/islands/WeatherForecast.tsx rename to examples/getting-started/src/getting-started-theme/components/islands/WeatherForecast.tsx diff --git a/examples/getting-started/getting-started-project/getting-started-app/components/modules/Footer/index.tsx b/examples/getting-started/src/getting-started-theme/components/modules/Footer/index.tsx similarity index 100% rename from examples/getting-started/getting-started-project/getting-started-app/components/modules/Footer/index.tsx rename to examples/getting-started/src/getting-started-theme/components/modules/Footer/index.tsx diff --git a/examples/getting-started/getting-started-project/getting-started-app/components/modules/Header/index.tsx b/examples/getting-started/src/getting-started-theme/components/modules/Header/index.tsx similarity index 100% rename from examples/getting-started/getting-started-project/getting-started-app/components/modules/Header/index.tsx rename to examples/getting-started/src/getting-started-theme/components/modules/Header/index.tsx diff --git a/examples/getting-started/getting-started-project/getting-started-app/components/modules/Weather/index.tsx b/examples/getting-started/src/getting-started-theme/components/modules/Weather/index.tsx similarity index 100% rename from examples/getting-started/getting-started-project/getting-started-app/components/modules/Weather/index.tsx rename to examples/getting-started/src/getting-started-theme/components/modules/Weather/index.tsx diff --git a/examples/getting-started/getting-started-project/getting-started-app/constants.ts b/examples/getting-started/src/getting-started-theme/constants.ts similarity index 100% rename from examples/getting-started/getting-started-project/getting-started-app/constants.ts rename to examples/getting-started/src/getting-started-theme/constants.ts diff --git a/examples/getting-started/getting-started-theme/fields.json b/examples/getting-started/src/getting-started-theme/fields.json similarity index 100% rename from examples/getting-started/getting-started-theme/fields.json rename to examples/getting-started/src/getting-started-theme/fields.json diff --git a/examples/getting-started/getting-started-theme/layouts/base.hubl.html b/examples/getting-started/src/getting-started-theme/layouts/base.hubl.html similarity index 92% rename from examples/getting-started/getting-started-theme/layouts/base.hubl.html rename to examples/getting-started/src/getting-started-theme/layouts/base.hubl.html index 51b7055..60515dc 100644 --- a/examples/getting-started/getting-started-theme/layouts/base.hubl.html +++ b/examples/getting-started/src/getting-started-theme/layouts/base.hubl.html @@ -17,7 +17,7 @@
{% block header %} - {% module 'main header' path="@projects/getting-started-project/getting-started-app/components/modules/Header" %} + {% module 'main header' path="@projects/getting-started-project/getting-started-theme/components/modules/Header" %} {% endblock header %} {# The main-content ID is used for the navigation skipper in the header.html file. More information on the navigation skipper can be found here: https://github.com/HubSpot/cms-theme-boilerplate/wiki/Accessibility #} @@ -26,7 +26,7 @@ {% endblock body %} {% block footer %} - {% module 'footer' path="@projects/getting-started-project/getting-started-app/components/modules/Footer" %} + {% module 'footer' path="@projects/getting-started-project/getting-started-theme/components/modules/Footer" %} {% endblock footer %}
diff --git a/examples/getting-started/getting-started-project/getting-started-app/package.json b/examples/getting-started/src/getting-started-theme/package.json similarity index 100% rename from examples/getting-started/getting-started-project/getting-started-app/package.json rename to examples/getting-started/src/getting-started-theme/package.json diff --git a/examples/getting-started/getting-started-project/getting-started-app/styles/footer.module.css b/examples/getting-started/src/getting-started-theme/styles/footer.module.css similarity index 100% rename from examples/getting-started/getting-started-project/getting-started-app/styles/footer.module.css rename to examples/getting-started/src/getting-started-theme/styles/footer.module.css diff --git a/examples/getting-started/getting-started-project/getting-started-app/styles/header.module.css b/examples/getting-started/src/getting-started-theme/styles/header.module.css similarity index 100% rename from examples/getting-started/getting-started-project/getting-started-app/styles/header.module.css rename to examples/getting-started/src/getting-started-theme/styles/header.module.css diff --git a/examples/getting-started/getting-started-project/getting-started-app/styles/weather.module.css b/examples/getting-started/src/getting-started-theme/styles/weather.module.css similarity index 100% rename from examples/getting-started/getting-started-project/getting-started-app/styles/weather.module.css rename to examples/getting-started/src/getting-started-theme/styles/weather.module.css diff --git a/examples/getting-started/getting-started-theme/theme.json b/examples/getting-started/src/getting-started-theme/theme.json similarity index 100% rename from examples/getting-started/getting-started-theme/theme.json rename to examples/getting-started/src/getting-started-theme/theme.json diff --git a/examples/getting-started/getting-started-project/getting-started-app/tsconfig.json b/examples/getting-started/src/getting-started-theme/tsconfig.json similarity index 100% rename from examples/getting-started/getting-started-project/getting-started-app/tsconfig.json rename to examples/getting-started/src/getting-started-theme/tsconfig.json diff --git a/examples/getting-started/getting-started-project/getting-started-app/utils.ts b/examples/getting-started/src/getting-started-theme/utils.ts similarity index 100% rename from examples/getting-started/getting-started-project/getting-started-app/utils.ts rename to examples/getting-started/src/getting-started-theme/utils.ts diff --git a/examples/getting-started/getting-started-theme/weather.hubl.html b/examples/getting-started/src/getting-started-theme/weather.hubl.html similarity index 69% rename from examples/getting-started/getting-started-theme/weather.hubl.html rename to examples/getting-started/src/getting-started-theme/weather.hubl.html index bc9150e..4eaf6b6 100644 --- a/examples/getting-started/getting-started-theme/weather.hubl.html +++ b/examples/getting-started/src/getting-started-theme/weather.hubl.html @@ -9,7 +9,7 @@ {% module "weather" - path="@projects/getting-started-project/getting-started-app/components/modules/Weather", + path="@projects/getting-started-project/getting-started-theme/components/modules/Weather", %} {% endblock body %} From 1be5e1ea431bf52cd48f07c6bce74886286aed5c Mon Sep 17 00:00:00 2001 From: Byron Matto Date: Tue, 29 Oct 2024 14:24:29 -0400 Subject: [PATCH 2/6] Move project theme into own directory --- .../.eslintrc.js | 22 ++ .../getting-started-project-theme/.gitignore | 3 + .../.node-version | 1 + .../getting-started-project-theme/.prettierrc | 6 + .../getting-started-project-theme/README.md | 200 ++++++++++++++++++ .../hsproject.json | 5 + .../package.json | 24 +++ .../src/getting-started-theme/Globals.d.ts | 0 .../getting-started-theme/assets/clear.svg | 0 .../getting-started-theme/assets/cloudy.svg | 0 .../src/getting-started-theme/assets/fog.svg | 0 .../src/getting-started-theme/assets/rain.svg | 0 .../src/getting-started-theme/assets/snow.svg | 0 .../getting-started-theme/assets/sprocket.svg | 0 .../assets/thunderstorm.svg | 0 .../components/WeatherCards.tsx | 0 .../components/islands/WeatherForecast.tsx | 0 .../components/modules/Footer/index.tsx | 0 .../components/modules/Header/index.tsx | 0 .../components/modules/Weather/index.tsx | 0 .../src/getting-started-theme/constants.ts | 0 .../src/getting-started-theme/fields.json | 0 .../layouts/base.hubl.html | 0 .../src/getting-started-theme/package.json | 2 +- .../styles/footer.module.css | 0 .../styles/header.module.css | 0 .../styles/weather.module.css | 0 .../src/getting-started-theme/theme.json | 3 + .../src/getting-started-theme/tsconfig.json | 0 .../src/getting-started-theme/utils.ts | 0 .../getting-started-theme/weather.hubl.html | 0 .../getting-started-app/.env | 1 + .../src/getting-started-theme/theme.json | 3 - 33 files changed, 266 insertions(+), 4 deletions(-) create mode 100644 examples/getting-started-project-theme/.eslintrc.js create mode 100644 examples/getting-started-project-theme/.gitignore create mode 100644 examples/getting-started-project-theme/.node-version create mode 100644 examples/getting-started-project-theme/.prettierrc create mode 100644 examples/getting-started-project-theme/README.md create mode 100644 examples/getting-started-project-theme/hsproject.json create mode 100644 examples/getting-started-project-theme/package.json rename examples/{getting-started => getting-started-project-theme}/src/getting-started-theme/Globals.d.ts (100%) rename examples/{getting-started => getting-started-project-theme}/src/getting-started-theme/assets/clear.svg (100%) rename examples/{getting-started => getting-started-project-theme}/src/getting-started-theme/assets/cloudy.svg (100%) rename examples/{getting-started => getting-started-project-theme}/src/getting-started-theme/assets/fog.svg (100%) rename examples/{getting-started => getting-started-project-theme}/src/getting-started-theme/assets/rain.svg (100%) rename examples/{getting-started => getting-started-project-theme}/src/getting-started-theme/assets/snow.svg (100%) rename examples/{getting-started => getting-started-project-theme}/src/getting-started-theme/assets/sprocket.svg (100%) rename examples/{getting-started => getting-started-project-theme}/src/getting-started-theme/assets/thunderstorm.svg (100%) rename examples/{getting-started => getting-started-project-theme}/src/getting-started-theme/components/WeatherCards.tsx (100%) rename examples/{getting-started => getting-started-project-theme}/src/getting-started-theme/components/islands/WeatherForecast.tsx (100%) rename examples/{getting-started => getting-started-project-theme}/src/getting-started-theme/components/modules/Footer/index.tsx (100%) rename examples/{getting-started => getting-started-project-theme}/src/getting-started-theme/components/modules/Header/index.tsx (100%) rename examples/{getting-started => getting-started-project-theme}/src/getting-started-theme/components/modules/Weather/index.tsx (100%) rename examples/{getting-started => getting-started-project-theme}/src/getting-started-theme/constants.ts (100%) rename examples/{getting-started => getting-started-project-theme}/src/getting-started-theme/fields.json (100%) rename examples/{getting-started => getting-started-project-theme}/src/getting-started-theme/layouts/base.hubl.html (100%) rename examples/{getting-started => getting-started-project-theme}/src/getting-started-theme/package.json (91%) rename examples/{getting-started => getting-started-project-theme}/src/getting-started-theme/styles/footer.module.css (100%) rename examples/{getting-started => getting-started-project-theme}/src/getting-started-theme/styles/header.module.css (100%) rename examples/{getting-started => getting-started-project-theme}/src/getting-started-theme/styles/weather.module.css (100%) create mode 100644 examples/getting-started-project-theme/src/getting-started-theme/theme.json rename examples/{getting-started => getting-started-project-theme}/src/getting-started-theme/tsconfig.json (100%) rename examples/{getting-started => getting-started-project-theme}/src/getting-started-theme/utils.ts (100%) rename examples/{getting-started => getting-started-project-theme}/src/getting-started-theme/weather.hubl.html (100%) create mode 100644 examples/getting-started/getting-started-project/getting-started-app/.env delete mode 100644 examples/getting-started/src/getting-started-theme/theme.json diff --git a/examples/getting-started-project-theme/.eslintrc.js b/examples/getting-started-project-theme/.eslintrc.js new file mode 100644 index 0000000..cbbe2ca --- /dev/null +++ b/examples/getting-started-project-theme/.eslintrc.js @@ -0,0 +1,22 @@ +module.exports = { + parserOptions: { + sourceType: 'module', + ecmaFeatures: { + jsx: true, + }, + }, + env: { + node: true, + es2021: true, + }, + extends: ['eslint:recommended', 'prettier', 'plugin:react/recommended'], + rules: { + 'react/react-in-jsx-scope': 'off', + 'react/prop-types': 'off', + }, + settings: { + react: { + version: '18.1', + }, + }, +}; diff --git a/examples/getting-started-project-theme/.gitignore b/examples/getting-started-project-theme/.gitignore new file mode 100644 index 0000000..b1ecb93 --- /dev/null +++ b/examples/getting-started-project-theme/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +hubspot.config.yml +dist diff --git a/examples/getting-started-project-theme/.node-version b/examples/getting-started-project-theme/.node-version new file mode 100644 index 0000000..8b0beab --- /dev/null +++ b/examples/getting-started-project-theme/.node-version @@ -0,0 +1 @@ +20.11.0 diff --git a/examples/getting-started-project-theme/.prettierrc b/examples/getting-started-project-theme/.prettierrc new file mode 100644 index 0000000..dc75c8a --- /dev/null +++ b/examples/getting-started-project-theme/.prettierrc @@ -0,0 +1,6 @@ +{ + "trailingComma": "all", + "tabWidth": 2, + "semi": true, + "singleQuote": true +} diff --git a/examples/getting-started-project-theme/README.md b/examples/getting-started-project-theme/README.md new file mode 100644 index 0000000..bc53dce --- /dev/null +++ b/examples/getting-started-project-theme/README.md @@ -0,0 +1,200 @@ +# Getting Started Example + +The getting started example within this directory covers a variety of key features/components of working with CMS React within a HubSpot website. This guide outlines the specifics of using CMS React primitives such as Modules, Fields, and Islands, as well as integrating third-party dependencies, styling, assets, and setting up local development tooling for your project. + +## Setup + +### Environment + +To set up your development environment to work with Project Themes, you’ll need the following: + +- A HubSpot account with CMS Free, Starter, Pro, or Enterprise access +- Node.js v20.0 or higher and the associated version of NPM + +## Creating and deploying a CMS React project + +Before we dive into running your first CMS React project, its important to understand the directory structure of this example: + +``` +getting-started-project-theme/ +├── package.json +├── hsproject.json +├── src/ +│ ├── getting-started-theme/ +│ │ ├── package.json +│ │ ├── tsconfig.json +│ │ ├── theme.json +│ │ └── ... +│ └── ... +└── ... +``` + +`getting-started-project-theme` is the root directory that contains your project configuration - `hsproject.json` - and the `src` directory. Also in this example we have a package.json file with some utility scripts for local development. The `src` directory contains your project's source code. Within the `src` directory you will find the `getting-started-theme` directory. This directory is where your HubL templates, HubL Modules, React Modules, and theme configuration lives. It is essentially a standard HubSpot theme, though within Project Themes you now have the ability to build React Modules which will live within the theme. + +> **Note** The directory naming convention mentioned above is not a requirement for your project Themes to work, but rather an example of how you could organize your project Themes. + +### Clone the `getting-started-project-theme` directory + +From your local directory for the following commands: + +```bash +git clone --filter=blob:none --no-checkout https://github.com/HubSpot/cms-react.git; +cd cms-react; +git sparse-checkout set --cone; +git checkout main; +git sparse-checkout set examples/getting-started-project-theme; +``` + +This will clone only the `getting-started-project-theme` directory from within cms-react repository down to your local file system. + +### Setting up your `hubspot.config.yaml` file + +In order to develop locally and deploy your code to your HubSpot portal. You will need to configure a `hubspot.config.yaml` file. Run `hs init` from the root of the repository and follow the prompts to setup your `hubspot.config.yaml` file. Keep in mind that when setting up JS assets for the first time, you will need to deactivate and regenerate your personal access key, ensuring it includes `CMS Pages`, `Design Manager` and `Developer Projects` permissions. See the [HubSpot CLI documentation](https://developers.hubspot.com/docs/cms/guides/getting-started-with-local-development) for more information. + +> **Warning:** If you are using an existing access key from a previous call to `hs init` or `hs auth`, you will need to deactivate and regenerate the access key to include new scopes necessary for local CMS React development. + +### Local development + +Now that our `hubspot.config.yaml` file is configured we can get to running and developing our project locally! Let's first install our dependencies. From the root of the `getting-started-project-theme` directory, run `npm install` in your terminal. This will install all your local dev tooling and any other dependencies found in your project's root package.json file. Next we will also need to run `npm install` from within the `/getting-started-theme` directory which will install all dependencies required for our CMS react code. With all of our deps installed, you can now run `npm run start` from the `getting-started-project-theme/src/getting-started-theme` directory. + +Once running, open up your browser to [https://hslocal.net:3000](https://hslocal.net:3000) to see the index page that links to all the modules associated to this project. Click on the "local version" of the "Weather" module to see a locally running instance of the module. The locally running instance will pick up any changes you make to your files instantly to streamline the feedback loop when iterating on your CMS components 🚀 + +Let's give this a test drive by opening up our `Weather` module found at `components/modules/Weather/index.tsx`. From within this file find the `` module field. That component has a `default` prop which signifies the starting value of the text field that a marketer will see in the page editor. Change the `default` prop's value to something else and save your changes. Take a look at your locally running instance of the [Weather` module](http://hslocal.net:3000/module/Weather) and it should now reflect your recent changes. + +### 4. Uploading and deploying to your portal + +With some changes in place, let's deploy our code to your HubSpot portal. Navigate back to the `/getting-started-project-theme/` directory and run `npm run deploy`. This will upload the `getting-started-project-theme` to your HubSpot account. Once uploaded, built, and deployed, you can create pages from the Templates, and use your React Modules within those pages. + +### Making more changes + +Let's say we want to show some default data on the initial load instead of forcing users to input a search before seeing weather data rendered. To do this, we can add a new module field for a `defaultCity` that a marketer can use within the context of the page editor to assign the module instance a default city to use at load time. + +To start, open the `/components/modules/Weather/index.tsx` in your code editor. Within this file you will see a `fields` variable that contains all of our module fields. These are the fields that a marketer can use to modify data for the Weather module from the WYSIWYG page editor. Since we already have a `TextField` component imported from `@hubspot/cms-components/fields` for our Weather Headline field, all we need to do is add a new `` for our defaultCity + +```js + +``` + +Once this is added, the `Component` export within this same file will now have access to the value of this new field via the `fieldValues` prop. since the `name` property on our `` component is `defaultCity` we can pull off this value from the `fieldValues` similarly to how we have for `headline` and add it to our island props like so: + +```js +const { defaultCity, headline } = fieldValues; +; +``` + +The final step is modify our `WeatherForecast` island component to enable the fetching weather data using the `defaultCity` value. To do this we have to make a couple updates: + +1. Include `defaultCity` in our props list +2. Update our `WeatherForecastProps` interface to include `defaultCity` +3. Add a `useEffect` that fetches the weather forecast with the `defaultCity` value +4. Add a loading state during a fetch + +The final component should resemble the following: + +```js +import { useEffect, useState } from 'react'; +import weatherStyles from '../../styles/weather.module.css'; +import { getWeatherForecast } from '../../utils.ts'; +import { WeatherForecast as WeatherForecastType } from '../../constants.ts'; +import { CurrentWeatherCard, UpcomingWeatherCard } from '../WeatherCards.tsx'; + +interface WeatherForecastProps { + headline: string; + defaultCity: string; // added defaultCity to the interface +} + +export default function WeatherForecast({ + headline, + defaultCity, // included defaultCity in props list +}: WeatherForecastProps) { + const [city, setCity] = useState(''); + const [weatherData, setWeatherData] = useState(); + + // adding useEffect to fetch weather forecast on component mount + useEffect(() => { + getWeatherForecast(defaultCity).then((data) => { + setWeatherData(data); + }); + }, []); + + const handleFetchWeather = () => { + getWeatherForecast(city).then((data) => { + setWeatherData(data); + }); + }; + + const isFetching: boolean = !weatherData; + const hasError: boolean = !isFetching && !!weatherData.error; + const hasWeatherData: boolean = + !isFetching && !hasError && !!weatherData.forecast; + const missingData = !isFetching && !hasWeatherData && !hasError; + + function WeatherForecast({ weatherData }) { + return ( + <> +
+ +
+
+ +
+ + ); + } + + return ( +
+

{headline}

+
+ setCity(event.target.value)} + /> + +
+
+ {isFetching &&

Loading...

} {/* add loading state during fetch */} + {hasError &&

Error occurred when fetching weather forecast

} + {hasWeatherData && } + {missingData && ( +

No results found for "{city}", please search another location

+ )} +
+
+ ); +} +``` + +Once you are satisfied with your changes, you only need to re-run `npm run deploy` in order to get the latest react module built and deployed to your portal. + +### 5. Previewing Local Changes on Proxied Pages + +In addition to locally viewing your modules, you can also preview your local CMS React components inside live HubL-rendered pages. To do this, create a page: + +- Go to Website Pages +- Click “Create”, then “Create Website Page" +- Write a page name and click “Create page” +- Switch your active theme to "CMS React - Getting Started Project Theme" and select the "Weather Forecast" template +- Name the page in the settings tab, then publish and preview it + +To proxy that page locally: + +- Run the local dev server as described above +- Visit the newly created page in your browser +- Open the sprocket menu and select `Open Local Dev Server` +- Your local JavaScript source changes will appear immediately in the context of the HubL page + +## Functionality + +This project includes templates, modules, module fields, and islands. Modules are the primary building block of the HubSpot CMS, and Islands enable client-side interactivity for React-powered modules. We have 3 modules: + +- **Header**: A React module without islands. +- **Footer**: Another example of a React module without islands. +- **Weather**: A module leveraging our island architecture to fetch and render data from an API client-side, enabling users to change the data they wish to fetch, and formatting dates using a third-party dependency. + +In addition to the above, we are using module css to scope our styles to a given file. For more styling options, check out our [Styling example](https://github.com/HubSpot/cms-react/tree/main/examples/styling). diff --git a/examples/getting-started-project-theme/hsproject.json b/examples/getting-started-project-theme/hsproject.json new file mode 100644 index 0000000..b1bf889 --- /dev/null +++ b/examples/getting-started-project-theme/hsproject.json @@ -0,0 +1,5 @@ +{ + "name": "getting-started-project-theme", + "srcDir": "src", + "platformVersion": "2023.2" +} diff --git a/examples/getting-started-project-theme/package.json b/examples/getting-started-project-theme/package.json new file mode 100644 index 0000000..f64d8ad --- /dev/null +++ b/examples/getting-started-project-theme/package.json @@ -0,0 +1,24 @@ +{ + "name": "getting-started-project-theme-example", + "description": "Getting started CMS Themes on Projects", + "license": "Apache-2.0", + "devDependencies": { + "@hubspot/cli": "latest", + "@hubspot/prettier-plugin-hubl": "latest", + "eslint": "^8.24.0", + "eslint-config-prettier": "^8.5.0", + "eslint-plugin-react": "^7.31.10", + "prettier": "^2.7.1", + "yarpm": "^1.2.0" + }, + "scripts": { + "start": "cd src/getting-started-theme && yarpm start", + "postinstall": "cd src/getting-started-theme && yarpm install", + "lint:js": "eslint . --ext .js,.jsx", + "prettier": "prettier . --check", + "deploy": "hs project upload ." + }, + "engines": { + "node": ">=16.0.0" + } +} diff --git a/examples/getting-started/src/getting-started-theme/Globals.d.ts b/examples/getting-started-project-theme/src/getting-started-theme/Globals.d.ts similarity index 100% rename from examples/getting-started/src/getting-started-theme/Globals.d.ts rename to examples/getting-started-project-theme/src/getting-started-theme/Globals.d.ts diff --git a/examples/getting-started/src/getting-started-theme/assets/clear.svg b/examples/getting-started-project-theme/src/getting-started-theme/assets/clear.svg similarity index 100% rename from examples/getting-started/src/getting-started-theme/assets/clear.svg rename to examples/getting-started-project-theme/src/getting-started-theme/assets/clear.svg diff --git a/examples/getting-started/src/getting-started-theme/assets/cloudy.svg b/examples/getting-started-project-theme/src/getting-started-theme/assets/cloudy.svg similarity index 100% rename from examples/getting-started/src/getting-started-theme/assets/cloudy.svg rename to examples/getting-started-project-theme/src/getting-started-theme/assets/cloudy.svg diff --git a/examples/getting-started/src/getting-started-theme/assets/fog.svg b/examples/getting-started-project-theme/src/getting-started-theme/assets/fog.svg similarity index 100% rename from examples/getting-started/src/getting-started-theme/assets/fog.svg rename to examples/getting-started-project-theme/src/getting-started-theme/assets/fog.svg diff --git a/examples/getting-started/src/getting-started-theme/assets/rain.svg b/examples/getting-started-project-theme/src/getting-started-theme/assets/rain.svg similarity index 100% rename from examples/getting-started/src/getting-started-theme/assets/rain.svg rename to examples/getting-started-project-theme/src/getting-started-theme/assets/rain.svg diff --git a/examples/getting-started/src/getting-started-theme/assets/snow.svg b/examples/getting-started-project-theme/src/getting-started-theme/assets/snow.svg similarity index 100% rename from examples/getting-started/src/getting-started-theme/assets/snow.svg rename to examples/getting-started-project-theme/src/getting-started-theme/assets/snow.svg diff --git a/examples/getting-started/src/getting-started-theme/assets/sprocket.svg b/examples/getting-started-project-theme/src/getting-started-theme/assets/sprocket.svg similarity index 100% rename from examples/getting-started/src/getting-started-theme/assets/sprocket.svg rename to examples/getting-started-project-theme/src/getting-started-theme/assets/sprocket.svg diff --git a/examples/getting-started/src/getting-started-theme/assets/thunderstorm.svg b/examples/getting-started-project-theme/src/getting-started-theme/assets/thunderstorm.svg similarity index 100% rename from examples/getting-started/src/getting-started-theme/assets/thunderstorm.svg rename to examples/getting-started-project-theme/src/getting-started-theme/assets/thunderstorm.svg diff --git a/examples/getting-started/src/getting-started-theme/components/WeatherCards.tsx b/examples/getting-started-project-theme/src/getting-started-theme/components/WeatherCards.tsx similarity index 100% rename from examples/getting-started/src/getting-started-theme/components/WeatherCards.tsx rename to examples/getting-started-project-theme/src/getting-started-theme/components/WeatherCards.tsx diff --git a/examples/getting-started/src/getting-started-theme/components/islands/WeatherForecast.tsx b/examples/getting-started-project-theme/src/getting-started-theme/components/islands/WeatherForecast.tsx similarity index 100% rename from examples/getting-started/src/getting-started-theme/components/islands/WeatherForecast.tsx rename to examples/getting-started-project-theme/src/getting-started-theme/components/islands/WeatherForecast.tsx diff --git a/examples/getting-started/src/getting-started-theme/components/modules/Footer/index.tsx b/examples/getting-started-project-theme/src/getting-started-theme/components/modules/Footer/index.tsx similarity index 100% rename from examples/getting-started/src/getting-started-theme/components/modules/Footer/index.tsx rename to examples/getting-started-project-theme/src/getting-started-theme/components/modules/Footer/index.tsx diff --git a/examples/getting-started/src/getting-started-theme/components/modules/Header/index.tsx b/examples/getting-started-project-theme/src/getting-started-theme/components/modules/Header/index.tsx similarity index 100% rename from examples/getting-started/src/getting-started-theme/components/modules/Header/index.tsx rename to examples/getting-started-project-theme/src/getting-started-theme/components/modules/Header/index.tsx diff --git a/examples/getting-started/src/getting-started-theme/components/modules/Weather/index.tsx b/examples/getting-started-project-theme/src/getting-started-theme/components/modules/Weather/index.tsx similarity index 100% rename from examples/getting-started/src/getting-started-theme/components/modules/Weather/index.tsx rename to examples/getting-started-project-theme/src/getting-started-theme/components/modules/Weather/index.tsx diff --git a/examples/getting-started/src/getting-started-theme/constants.ts b/examples/getting-started-project-theme/src/getting-started-theme/constants.ts similarity index 100% rename from examples/getting-started/src/getting-started-theme/constants.ts rename to examples/getting-started-project-theme/src/getting-started-theme/constants.ts diff --git a/examples/getting-started/src/getting-started-theme/fields.json b/examples/getting-started-project-theme/src/getting-started-theme/fields.json similarity index 100% rename from examples/getting-started/src/getting-started-theme/fields.json rename to examples/getting-started-project-theme/src/getting-started-theme/fields.json diff --git a/examples/getting-started/src/getting-started-theme/layouts/base.hubl.html b/examples/getting-started-project-theme/src/getting-started-theme/layouts/base.hubl.html similarity index 100% rename from examples/getting-started/src/getting-started-theme/layouts/base.hubl.html rename to examples/getting-started-project-theme/src/getting-started-theme/layouts/base.hubl.html diff --git a/examples/getting-started/src/getting-started-theme/package.json b/examples/getting-started-project-theme/src/getting-started-theme/package.json similarity index 91% rename from examples/getting-started/src/getting-started-theme/package.json rename to examples/getting-started-project-theme/src/getting-started-theme/package.json index 826edda..241a74a 100644 --- a/examples/getting-started/src/getting-started-theme/package.json +++ b/examples/getting-started-project-theme/src/getting-started-theme/package.json @@ -16,7 +16,7 @@ "vitest": "^0.24.3" }, "scripts": { - "start": "hs-cms-dev-server .", + "start": "hs-cms-dev-server . --ssl", "test": "vitest" } } diff --git a/examples/getting-started/src/getting-started-theme/styles/footer.module.css b/examples/getting-started-project-theme/src/getting-started-theme/styles/footer.module.css similarity index 100% rename from examples/getting-started/src/getting-started-theme/styles/footer.module.css rename to examples/getting-started-project-theme/src/getting-started-theme/styles/footer.module.css diff --git a/examples/getting-started/src/getting-started-theme/styles/header.module.css b/examples/getting-started-project-theme/src/getting-started-theme/styles/header.module.css similarity index 100% rename from examples/getting-started/src/getting-started-theme/styles/header.module.css rename to examples/getting-started-project-theme/src/getting-started-theme/styles/header.module.css diff --git a/examples/getting-started/src/getting-started-theme/styles/weather.module.css b/examples/getting-started-project-theme/src/getting-started-theme/styles/weather.module.css similarity index 100% rename from examples/getting-started/src/getting-started-theme/styles/weather.module.css rename to examples/getting-started-project-theme/src/getting-started-theme/styles/weather.module.css diff --git a/examples/getting-started-project-theme/src/getting-started-theme/theme.json b/examples/getting-started-project-theme/src/getting-started-theme/theme.json new file mode 100644 index 0000000..1aac0c2 --- /dev/null +++ b/examples/getting-started-project-theme/src/getting-started-theme/theme.json @@ -0,0 +1,3 @@ +{ + "label": "CMS React - Getting Started Project Theme" +} diff --git a/examples/getting-started/src/getting-started-theme/tsconfig.json b/examples/getting-started-project-theme/src/getting-started-theme/tsconfig.json similarity index 100% rename from examples/getting-started/src/getting-started-theme/tsconfig.json rename to examples/getting-started-project-theme/src/getting-started-theme/tsconfig.json diff --git a/examples/getting-started/src/getting-started-theme/utils.ts b/examples/getting-started-project-theme/src/getting-started-theme/utils.ts similarity index 100% rename from examples/getting-started/src/getting-started-theme/utils.ts rename to examples/getting-started-project-theme/src/getting-started-theme/utils.ts diff --git a/examples/getting-started/src/getting-started-theme/weather.hubl.html b/examples/getting-started-project-theme/src/getting-started-theme/weather.hubl.html similarity index 100% rename from examples/getting-started/src/getting-started-theme/weather.hubl.html rename to examples/getting-started-project-theme/src/getting-started-theme/weather.hubl.html diff --git a/examples/getting-started/getting-started-project/getting-started-app/.env b/examples/getting-started/getting-started-project/getting-started-app/.env new file mode 100644 index 0000000..5fec21b --- /dev/null +++ b/examples/getting-started/getting-started-project/getting-started-app/.env @@ -0,0 +1 @@ +HS_TEST_SECRET=pears diff --git a/examples/getting-started/src/getting-started-theme/theme.json b/examples/getting-started/src/getting-started-theme/theme.json deleted file mode 100644 index 3e4f466..0000000 --- a/examples/getting-started/src/getting-started-theme/theme.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "label": "CMS React - Getting Started Theme" -} From 2517b33fc5ad780dee6a2858b429a0bad3eebc31 Mon Sep 17 00:00:00 2001 From: Byron Matto Date: Tue, 29 Oct 2024 14:39:23 -0400 Subject: [PATCH 3/6] Revert "Example now in "Unified" style" This reverts commit aa2ca6c534360c588df5c9a71a713e2a8befdc18. --- .../layouts/base.hubl.html | 4 +- .../getting-started-theme/weather.hubl.html | 2 +- .../getting-started-app/Globals.d.ts | 1 + .../getting-started-app/assets/clear.svg | 25 +++ .../getting-started-app/assets/cloudy.svg | 22 +++ .../getting-started-app/assets/fog.svg | 71 ++++++++ .../getting-started-app/assets/rain.svg | 113 +++++++++++++ .../getting-started-app/assets/snow.svg | 143 ++++++++++++++++ .../getting-started-app/assets/sprocket.svg | 14 ++ .../assets/thunderstorm.svg | 62 +++++++ .../getting-started-app/cms-assets.json | 4 + .../components/WeatherCards.tsx | 63 ++++++++ .../components/islands/WeatherForecast.tsx | 61 +++++++ .../components/modules/Footer/index.tsx | 20 +++ .../components/modules/Header/index.tsx | 40 +++++ .../components/modules/Weather/index.tsx | 22 +++ .../getting-started-app/constants.ts | 68 ++++++++ .../getting-started-app/package.json | 22 +++ .../styles/footer.module.css | 5 + .../styles/header.module.css | 30 ++++ .../styles/weather.module.css | 152 ++++++++++++++++++ .../getting-started-app/tsconfig.json | 18 +++ .../getting-started-app/utils.ts | 100 ++++++++++++ .../hsproject.json | 2 +- .../getting-started-theme/fields.json | 1 + .../layouts/base.hubl.html | 36 +++++ .../getting-started-theme/theme.json | 3 + .../getting-started-theme/weather.hubl.html | 15 ++ examples/getting-started/package.json | 2 +- 29 files changed, 1116 insertions(+), 5 deletions(-) create mode 100644 examples/getting-started/getting-started-project/getting-started-app/Globals.d.ts create mode 100644 examples/getting-started/getting-started-project/getting-started-app/assets/clear.svg create mode 100644 examples/getting-started/getting-started-project/getting-started-app/assets/cloudy.svg create mode 100644 examples/getting-started/getting-started-project/getting-started-app/assets/fog.svg create mode 100644 examples/getting-started/getting-started-project/getting-started-app/assets/rain.svg create mode 100644 examples/getting-started/getting-started-project/getting-started-app/assets/snow.svg create mode 100644 examples/getting-started/getting-started-project/getting-started-app/assets/sprocket.svg create mode 100644 examples/getting-started/getting-started-project/getting-started-app/assets/thunderstorm.svg create mode 100644 examples/getting-started/getting-started-project/getting-started-app/cms-assets.json create mode 100644 examples/getting-started/getting-started-project/getting-started-app/components/WeatherCards.tsx create mode 100644 examples/getting-started/getting-started-project/getting-started-app/components/islands/WeatherForecast.tsx create mode 100644 examples/getting-started/getting-started-project/getting-started-app/components/modules/Footer/index.tsx create mode 100644 examples/getting-started/getting-started-project/getting-started-app/components/modules/Header/index.tsx create mode 100644 examples/getting-started/getting-started-project/getting-started-app/components/modules/Weather/index.tsx create mode 100644 examples/getting-started/getting-started-project/getting-started-app/constants.ts create mode 100644 examples/getting-started/getting-started-project/getting-started-app/package.json create mode 100644 examples/getting-started/getting-started-project/getting-started-app/styles/footer.module.css create mode 100644 examples/getting-started/getting-started-project/getting-started-app/styles/header.module.css create mode 100644 examples/getting-started/getting-started-project/getting-started-app/styles/weather.module.css create mode 100644 examples/getting-started/getting-started-project/getting-started-app/tsconfig.json create mode 100644 examples/getting-started/getting-started-project/getting-started-app/utils.ts rename examples/getting-started/{ => getting-started-project}/hsproject.json (78%) create mode 100644 examples/getting-started/getting-started-theme/fields.json create mode 100644 examples/getting-started/getting-started-theme/layouts/base.hubl.html create mode 100644 examples/getting-started/getting-started-theme/theme.json create mode 100644 examples/getting-started/getting-started-theme/weather.hubl.html diff --git a/examples/getting-started-project-theme/src/getting-started-theme/layouts/base.hubl.html b/examples/getting-started-project-theme/src/getting-started-theme/layouts/base.hubl.html index 60515dc..51b7055 100644 --- a/examples/getting-started-project-theme/src/getting-started-theme/layouts/base.hubl.html +++ b/examples/getting-started-project-theme/src/getting-started-theme/layouts/base.hubl.html @@ -17,7 +17,7 @@
{% block header %} - {% module 'main header' path="@projects/getting-started-project/getting-started-theme/components/modules/Header" %} + {% module 'main header' path="@projects/getting-started-project/getting-started-app/components/modules/Header" %} {% endblock header %} {# The main-content ID is used for the navigation skipper in the header.html file. More information on the navigation skipper can be found here: https://github.com/HubSpot/cms-theme-boilerplate/wiki/Accessibility #} @@ -26,7 +26,7 @@ {% endblock body %} {% block footer %} - {% module 'footer' path="@projects/getting-started-project/getting-started-theme/components/modules/Footer" %} + {% module 'footer' path="@projects/getting-started-project/getting-started-app/components/modules/Footer" %} {% endblock footer %}
diff --git a/examples/getting-started-project-theme/src/getting-started-theme/weather.hubl.html b/examples/getting-started-project-theme/src/getting-started-theme/weather.hubl.html index 4eaf6b6..bc9150e 100644 --- a/examples/getting-started-project-theme/src/getting-started-theme/weather.hubl.html +++ b/examples/getting-started-project-theme/src/getting-started-theme/weather.hubl.html @@ -9,7 +9,7 @@ {% module "weather" - path="@projects/getting-started-project/getting-started-theme/components/modules/Weather", + path="@projects/getting-started-project/getting-started-app/components/modules/Weather", %} {% endblock body %} diff --git a/examples/getting-started/getting-started-project/getting-started-app/Globals.d.ts b/examples/getting-started/getting-started-project/getting-started-app/Globals.d.ts new file mode 100644 index 0000000..60260a3 --- /dev/null +++ b/examples/getting-started/getting-started-project/getting-started-app/Globals.d.ts @@ -0,0 +1 @@ +declare module '*.module.css'; diff --git a/examples/getting-started/getting-started-project/getting-started-app/assets/clear.svg b/examples/getting-started/getting-started-project/getting-started-app/assets/clear.svg new file mode 100644 index 0000000..d192b7f --- /dev/null +++ b/examples/getting-started/getting-started-project/getting-started-app/assets/clear.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/examples/getting-started/getting-started-project/getting-started-app/assets/cloudy.svg b/examples/getting-started/getting-started-project/getting-started-app/assets/cloudy.svg new file mode 100644 index 0000000..283e3cc --- /dev/null +++ b/examples/getting-started/getting-started-project/getting-started-app/assets/cloudy.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + diff --git a/examples/getting-started/getting-started-project/getting-started-app/assets/fog.svg b/examples/getting-started/getting-started-project/getting-started-app/assets/fog.svg new file mode 100644 index 0000000..8431c61 --- /dev/null +++ b/examples/getting-started/getting-started-project/getting-started-app/assets/fog.svg @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/getting-started/getting-started-project/getting-started-app/assets/rain.svg b/examples/getting-started/getting-started-project/getting-started-app/assets/rain.svg new file mode 100644 index 0000000..d96ac2f --- /dev/null +++ b/examples/getting-started/getting-started-project/getting-started-app/assets/rain.svg @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/getting-started/getting-started-project/getting-started-app/assets/snow.svg b/examples/getting-started/getting-started-project/getting-started-app/assets/snow.svg new file mode 100644 index 0000000..baf2f5f --- /dev/null +++ b/examples/getting-started/getting-started-project/getting-started-app/assets/snow.svg @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/getting-started/getting-started-project/getting-started-app/assets/sprocket.svg b/examples/getting-started/getting-started-project/getting-started-app/assets/sprocket.svg new file mode 100644 index 0000000..cb945b6 --- /dev/null +++ b/examples/getting-started/getting-started-project/getting-started-app/assets/sprocket.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/examples/getting-started/getting-started-project/getting-started-app/assets/thunderstorm.svg b/examples/getting-started/getting-started-project/getting-started-app/assets/thunderstorm.svg new file mode 100644 index 0000000..0f09655 --- /dev/null +++ b/examples/getting-started/getting-started-project/getting-started-app/assets/thunderstorm.svg @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/getting-started/getting-started-project/getting-started-app/cms-assets.json b/examples/getting-started/getting-started-project/getting-started-app/cms-assets.json new file mode 100644 index 0000000..f7037b1 --- /dev/null +++ b/examples/getting-started/getting-started-project/getting-started-app/cms-assets.json @@ -0,0 +1,4 @@ +{ + "label": "Getting started", + "outputPath": "" +} diff --git a/examples/getting-started/getting-started-project/getting-started-app/components/WeatherCards.tsx b/examples/getting-started/getting-started-project/getting-started-app/components/WeatherCards.tsx new file mode 100644 index 0000000..5f27ed8 --- /dev/null +++ b/examples/getting-started/getting-started-project/getting-started-app/components/WeatherCards.tsx @@ -0,0 +1,63 @@ +import dayjs from 'dayjs'; +import weatherStyles from '../styles/weather.module.css'; +import { getWeatherIcon } from '../utils.ts'; +import { ForecastData } from '../constants.ts'; + +interface WeatherProps { + city: string; + forecast: ForecastData[]; +} +interface CurrentWeatherCardProps { + weatherData: WeatherProps; +} + +export function CurrentWeatherCard({ weatherData }: CurrentWeatherCardProps) { + const { forecast, city } = weatherData; + const currentDay = forecast[0]; + + return ( +
+
+ {`${city}-weather-icon-${currentDay.weather_code}`} +

+ {currentDay.apparent_temperature_max}° + F +

+
+

{city}

+
+ ); +} + +interface UpcomingWeatherCardProps { + weatherData: WeatherProps; +} + +export function UpcomingWeatherCard({ weatherData }: UpcomingWeatherCardProps) { + const { city, forecast } = weatherData; + + return ( + <> + {forecast?.map((weather, index: number) => { + if (index === 0) return null; + + return ( +
+ {dayjs(weather.time).format('dddd')} + {`${city}-weather-icon-${weather.weather_code}`} +

+ {weather.apparent_temperature_max}° + F +

+
+ ); + })} + + ); +} diff --git a/examples/getting-started/getting-started-project/getting-started-app/components/islands/WeatherForecast.tsx b/examples/getting-started/getting-started-project/getting-started-app/components/islands/WeatherForecast.tsx new file mode 100644 index 0000000..4536166 --- /dev/null +++ b/examples/getting-started/getting-started-project/getting-started-app/components/islands/WeatherForecast.tsx @@ -0,0 +1,61 @@ +import { useState } from 'react'; +import weatherStyles from '../../styles/weather.module.css'; +import { getWeatherForecast } from '../../utils.ts'; +import { WeatherForecast as WeatherForecastType } from '../../constants.ts'; +import { CurrentWeatherCard, UpcomingWeatherCard } from '../WeatherCards.tsx'; + +interface WeatherForecastProps { + headline: string; +} + +export default function WeatherForecast({ headline }: WeatherForecastProps) { + const [city, setCity] = useState(''); + const [weatherData, setWeatherData] = useState(); + + const handleFetchWeather = () => { + getWeatherForecast(city).then((data) => { + setWeatherData(data); + }); + }; + + const isFetching: boolean = !weatherData; + const hasError: boolean = !isFetching && !!weatherData.error; + const hasWeatherData: boolean = + !isFetching && !hasError && !!weatherData.forecast; + const missingData = !isFetching && !hasWeatherData && !hasError; + + function WeatherForecast({ weatherData }) { + return ( + <> +
+ +
+
+ +
+ + ); + } + + return ( +
+

{headline}

+
+ setCity(event.target.value)} + /> + +
+
+ {isFetching &&

Search for a city to see the weather forecast

} + {hasError &&

Error occurred when fetching weather forecast

} + {hasWeatherData && } + {missingData && ( +

No results found for "{city}", please search another location

+ )} +
+
+ ); +} diff --git a/examples/getting-started/getting-started-project/getting-started-app/components/modules/Footer/index.tsx b/examples/getting-started/getting-started-project/getting-started-app/components/modules/Footer/index.tsx new file mode 100644 index 0000000..3f1ee0c --- /dev/null +++ b/examples/getting-started/getting-started-project/getting-started-app/components/modules/Footer/index.tsx @@ -0,0 +1,20 @@ +import { ModuleFields, TextField } from '@hubspot/cms-components/fields'; +import footerStyles from '../../../styles/footer.module.css'; + +export function Component({ fieldValues }: any) { + return ( +
+

{fieldValues.footerText}

+
+ ); +} + +export const fields = ( + + + +); + +export const meta = { + label: 'Footer Module', +}; diff --git a/examples/getting-started/getting-started-project/getting-started-app/components/modules/Header/index.tsx b/examples/getting-started/getting-started-project/getting-started-app/components/modules/Header/index.tsx new file mode 100644 index 0000000..2d99c37 --- /dev/null +++ b/examples/getting-started/getting-started-project/getting-started-app/components/modules/Header/index.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import { Menu, logInfo } from '@hubspot/cms-components'; +import { + ImageField, + MenuField, + ModuleFields, +} from '@hubspot/cms-components/fields'; +import logo from '../../../assets/sprocket.svg'; +import headerStyles from '../../../styles/header.module.css'; + +export function Component({ fieldValues }: any) { + const { src, alt, width, height } = fieldValues.logo; + + return ( +
+ +
+ ); +} + +const DEFAULT_MENU_ID = ' + + + +); + +export const meta = { + label: 'Header Module', +}; diff --git a/examples/getting-started/getting-started-project/getting-started-app/components/modules/Weather/index.tsx b/examples/getting-started/getting-started-project/getting-started-app/components/modules/Weather/index.tsx new file mode 100644 index 0000000..3478a4d --- /dev/null +++ b/examples/getting-started/getting-started-project/getting-started-app/components/modules/Weather/index.tsx @@ -0,0 +1,22 @@ +import { Island } from '@hubspot/cms-components'; +import WeatherForecast from '../../islands/WeatherForecast.tsx?island'; +import { ModuleFields, TextField } from '@hubspot/cms-components/fields'; + +export function Component({ fieldValues }: any) { + const { headline } = fieldValues; + return ; +} + +export const fields = ( + + + +); + +export const meta = { + label: 'Weather Module', +}; diff --git a/examples/getting-started/getting-started-project/getting-started-app/constants.ts b/examples/getting-started/getting-started-project/getting-started-app/constants.ts new file mode 100644 index 0000000..5bcbf02 --- /dev/null +++ b/examples/getting-started/getting-started-project/getting-started-app/constants.ts @@ -0,0 +1,68 @@ +import CLEAR from './assets/clear.svg'; +import RAIN from './assets/rain.svg'; +import SNOW from './assets/snow.svg'; +import THUNDERSTORM from './assets/thunderstorm.svg'; +import FOG from './assets/fog.svg'; +import CLOUDY from './assets/cloudy.svg'; + +export const ICON_MAP = { + CLEAR, + RAIN, + SNOW, + THUNDERSTORM, + FOG, + CLOUDY, +}; + +export const FORECAST_BASE_URL = 'https://api.open-meteo.com/v1/forecast'; // https://open-meteo.com/en/docs +export const LAT_LNG_BASE_URL = + 'https://geocoding-api.open-meteo.com/v1/search'; + +export interface Forecast { + time: string[]; + apparent_temperature_max: number[]; + weather_code: number[]; +} + +export interface ForecastData { + time: string; + apparent_temperature_max: number; + weather_code: number; +} + +interface LocationResult { + latitude: number; + longitude: number; +} + +export interface LocationResponse { + results: LocationResult[]; +} + +export interface ForecastResponse { + daily: Forecast; +} + +export interface WeatherForecast { + city: string; + forecast: ForecastData[]; + error?: string; +} + +interface DailyUnits { + time: string; + apparent_temperature_max: string; + weather_code: string; +} + +export interface ApiResponse { + latitude: number; + longitude: number; + generationtime_ms: number; + utc_offset_seconds: number; + timezone: string; + timezone_abbreviation: string; + elevation: number; + daily_units: DailyUnits; + daily: Forecast; +} diff --git a/examples/getting-started/getting-started-project/getting-started-app/package.json b/examples/getting-started/getting-started-project/getting-started-app/package.json new file mode 100644 index 0000000..826edda --- /dev/null +++ b/examples/getting-started/getting-started-project/getting-started-app/package.json @@ -0,0 +1,22 @@ +{ + "name": "getting-started-example-app", + "version": "0.1.0", + "type": "module", + "dependencies": { + "@hubspot/cms-components": "latest", + "dayjs": "^1.11.11", + "prop-types": "^15.8.1", + "react": "^18.1.0" + }, + "devDependencies": { + "@hubspot/cms-dev-server": "latest", + "@testing-library/react": "^13.4.0", + "@vitejs/plugin-react": "^2.1.0", + "jsdom": "^20.0.1", + "vitest": "^0.24.3" + }, + "scripts": { + "start": "hs-cms-dev-server .", + "test": "vitest" + } +} diff --git a/examples/getting-started/getting-started-project/getting-started-app/styles/footer.module.css b/examples/getting-started/getting-started-project/getting-started-app/styles/footer.module.css new file mode 100644 index 0000000..43dd42c --- /dev/null +++ b/examples/getting-started/getting-started-project/getting-started-app/styles/footer.module.css @@ -0,0 +1,5 @@ +.footer { + text-align: center; + font-weight: bold; + font-size: 2em; +} diff --git a/examples/getting-started/getting-started-project/getting-started-app/styles/header.module.css b/examples/getting-started/getting-started-project/getting-started-app/styles/header.module.css new file mode 100644 index 0000000..584e8f9 --- /dev/null +++ b/examples/getting-started/getting-started-project/getting-started-app/styles/header.module.css @@ -0,0 +1,30 @@ +.wrapper { + width: 100%; + background-color: transparent; + + & nav { + display: flex; + align-items: center; + justify-content: space-between; + flex-direction: row; + padding: 15px 25px; + + & ul { + gap: 20px; + list-style: none; + margin: 0; + padding: 0; + display: flex; + + & li { + & a { + text-decoration: none; + color: #ff7a59; + &:hover { + color: #2d3e50; + } + } + } + } + } +} diff --git a/examples/getting-started/getting-started-project/getting-started-app/styles/weather.module.css b/examples/getting-started/getting-started-project/getting-started-app/styles/weather.module.css new file mode 100644 index 0000000..7cef0a0 --- /dev/null +++ b/examples/getting-started/getting-started-project/getting-started-app/styles/weather.module.css @@ -0,0 +1,152 @@ +:root { + --primary-color: #ff7a59; + --primary-color-dark: #e66e50; + --primary-color-med: #ffbcac; + --secondary-color: #dfe3eb; + --accent-color: #2d3e50; + --light-accent-color: #eaf0f6; +} + +.wrapper { + background-color: var(--accent-color); + min-height: 40vh; + padding: 50px; + font-family: sans-serif; + + & .currentWeather { + min-height: 670px; + } + + & h1 { + text-align: center; + margin-bottom: 50px; + color: white; + font-size: 3rem; + } + + & h2 { + text-align: center; + font-size: 2rem; + color: white; + } + + & input[type="text"] { + border-radius: 5px; + border: none; + padding: 10px 15px; + font-size: 16px; + background-color: var(--light-accent-color); + } + + & button { + border-radius: 5px; + border:none; + background-color: var(--primary-color); + color: white; + padding: 10px 12px; + transition: background-color 0.3s; + cursor: pointer; + font-size: 14px; + + &:hover { + background-color: var(--primary-color-dark); + transition: background-color 0.3s; + } + } + + & .form { + display: flex; + justify-content: center; + margin-top: 20px; + align-items: center; + gap: 10px; + margin-bottom: 50px; + } + + & .cardContainer { + display: flex; + gap: 20px; + justify-content: center; + align-items: flex-start; + max-width: 300px; + margin: auto; + } + + & .card { + background-color: var(--secondary-color); + padding: 10px; + border-radius: 5px; + box-shadow: 0 0 4px rgba(0, 0, 0, 0.2); + min-width: 165px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + & img { + height: 100px; + } + + & h3 { + margin: 0 auto 10px auto; + } + } + + & .current { + background-color: var(--primary-color); + padding: 0px 25px 25px; + border-radius: 5px; + box-shadow: 0 0 4px rgba(0, 0, 0, 0.2); + max-width: 350px; + margin:auto; + min-height: 400px; + margin-bottom: 50px; + display: flex; + justify-content: center; + flex-direction: column; + + & h2 { + margin: 0 auto 10px auto; + } + + & .city { + text-align: center; + color: white; + } + + & .country { + text-align: center; + color: var(--primary-color-med); + } + + & h3 { + text-align: center; + color: white; + font-size: 3.5rem; + margin: 0; + position: relative; + + & .unit { + font-size: 22px; + position: absolute; + right: 4px; + top: 31px; + color: var(--primary-color-med); + } + } + + & .condition { + position: relative; + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: flex-start; + margin-bottom: 25px; + + & img { + width:200px + } + } + } +} diff --git a/examples/getting-started/getting-started-project/getting-started-app/tsconfig.json b/examples/getting-started/getting-started-project/getting-started-app/tsconfig.json new file mode 100644 index 0000000..49cf7c7 --- /dev/null +++ b/examples/getting-started/getting-started-project/getting-started-app/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "esnext", + "module": "Node16", + "moduleResolution": "Node16", + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "allowImportingTsExtensions": true, + "noEmit": true, + "isolatedModules": true, + "jsx": "react-jsx", + "skipLibCheck": true, + "types": ["vite/client", "vitest/globals"] + }, + "include": ["components/**/*"], + "exclude": ["node_modules"] +} diff --git a/examples/getting-started/getting-started-project/getting-started-app/utils.ts b/examples/getting-started/getting-started-project/getting-started-app/utils.ts new file mode 100644 index 0000000..a72f47d --- /dev/null +++ b/examples/getting-started/getting-started-project/getting-started-app/utils.ts @@ -0,0 +1,100 @@ +import { logInfo } from '@hubspot/cms-components'; +import { + ApiResponse, + FORECAST_BASE_URL, + Forecast, + ForecastData, + ICON_MAP, + LAT_LNG_BASE_URL, + LocationResponse, + WeatherForecast, +} from './constants.ts'; + +// weatherCode's are pulled from the "WMO Weather interpretation codes" section +// of the open-meteo docs: https://open-meteo.com/en/docs +export function getWeatherIcon(weatherCode: string) { + switch (weatherCode) { + case '0': + case '1': + case 'Clear': + return ICON_MAP.CLEAR; + + case '2': + case '3': + return ICON_MAP.CLOUDY; + + case '51': + case '53': + case '55': + case '56': + case '57': + case '61': + case '63': + case '65': + case '66': + case '67': + case '80': + case '81': + case '82': + return ICON_MAP.RAIN; + + case '71': + case '73': + case '75': + case '77': + case '85': + case '86': + return ICON_MAP.SNOW; + + case '95': + case '96': + case '99': + return ICON_MAP.THUNDERSTORM; + + case '45': + case '48': + return ICON_MAP.FOG; + + default: + return ''; + } +} + +function transformResponseData(data: Forecast): ForecastData[] { + const { time, apparent_temperature_max, weather_code } = data; + const transformedData = time.map((day: string, index: number) => ({ + time: day, + apparent_temperature_max: apparent_temperature_max[index], + weather_code: weather_code[index], + })); + + return transformedData; +} + +export async function getWeatherForecast( + city: string, +): Promise { + try { + const fetchLocationData = await fetch( + `${LAT_LNG_BASE_URL}?name=${city}&count=1&language=en&format=json`, + ); + + const locationData: LocationResponse = await fetchLocationData.json(); + + if (fetchLocationData.status === 200 && !locationData.results) { + return { city, forecast: undefined }; + } + + const { longitude, latitude } = locationData.results[0]; + const forecastResponse = await fetch( + `${FORECAST_BASE_URL}?latitude=${latitude}&longitude=${longitude}&temperature_unit=fahrenheit&forecast_days=3&daily=apparent_temperature_max,weather_code`, + ); + + const forecast: ApiResponse = await forecastResponse.json(); + const transformedForecast = transformResponseData(forecast.daily); + + return { city, forecast: transformedForecast }; + } catch (error) { + return { city, error, forecast: undefined }; + } +} diff --git a/examples/getting-started/hsproject.json b/examples/getting-started/getting-started-project/hsproject.json similarity index 78% rename from examples/getting-started/hsproject.json rename to examples/getting-started/getting-started-project/hsproject.json index f38bacf..7de2a73 100644 --- a/examples/getting-started/hsproject.json +++ b/examples/getting-started/getting-started-project/hsproject.json @@ -1,5 +1,5 @@ { "name": "getting-started-project", - "srcDir": "src", + "srcDir": ".", "platformVersion": "2023.2" } diff --git a/examples/getting-started/getting-started-theme/fields.json b/examples/getting-started/getting-started-theme/fields.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/examples/getting-started/getting-started-theme/fields.json @@ -0,0 +1 @@ +[] diff --git a/examples/getting-started/getting-started-theme/layouts/base.hubl.html b/examples/getting-started/getting-started-theme/layouts/base.hubl.html new file mode 100644 index 0000000..51b7055 --- /dev/null +++ b/examples/getting-started/getting-started-theme/layouts/base.hubl.html @@ -0,0 +1,36 @@ + + + + + + {% if page_meta.html_title or pageTitle %} + {{ page_meta.html_title or pageTitle }} + {% endif %} + {% if brand_settings.primaryFavicon.src %} + + {% endif %} + + {{ standard_header_includes }} + + +
+ {% block header %} + {% module 'main header' path="@projects/getting-started-project/getting-started-app/components/modules/Header" %} + {% endblock header %} + + {# The main-content ID is used for the navigation skipper in the header.html file. More information on the navigation skipper can be found here: https://github.com/HubSpot/cms-theme-boilerplate/wiki/Accessibility #} + + {% block body %} + {% endblock body %} + + {% block footer %} + {% module 'footer' path="@projects/getting-started-project/getting-started-app/components/modules/Footer" %} + {% endblock footer %} +
+ + {# To see a full list of what is included via standard_footer_includes please reference this article: https://developers.hubspot.com/docs/cms/hubl/variables#required-page-template-variables #} + {{ standard_footer_includes }} + + diff --git a/examples/getting-started/getting-started-theme/theme.json b/examples/getting-started/getting-started-theme/theme.json new file mode 100644 index 0000000..3e4f466 --- /dev/null +++ b/examples/getting-started/getting-started-theme/theme.json @@ -0,0 +1,3 @@ +{ + "label": "CMS React - Getting Started Theme" +} diff --git a/examples/getting-started/getting-started-theme/weather.hubl.html b/examples/getting-started/getting-started-theme/weather.hubl.html new file mode 100644 index 0000000..bc9150e --- /dev/null +++ b/examples/getting-started/getting-started-theme/weather.hubl.html @@ -0,0 +1,15 @@ + +{% extends "./layouts/base.hubl.html" %} + +{% block body %} + + {% module + "weather" + path="@projects/getting-started-project/getting-started-app/components/modules/Weather", + %} + +{% endblock body %} diff --git a/examples/getting-started/package.json b/examples/getting-started/package.json index 9365759..59c2455 100644 --- a/examples/getting-started/package.json +++ b/examples/getting-started/package.json @@ -18,7 +18,7 @@ "prettier": "prettier . --check", "watch:hubl": "hs watch getting-started-theme getting-started-theme", "upload:hubl": "hs upload getting-started-theme getting-started-theme", - "deploy": "hs project upload ." + "deploy": "hs project upload getting-started-project" }, "engines": { "node": ">=16.0.0" From 7701690281fc17625d8f0ddabdfd04144d8072d2 Mon Sep 17 00:00:00 2001 From: Byron Matto Date: Tue, 29 Oct 2024 14:42:55 -0400 Subject: [PATCH 4/6] remove .env file --- .../getting-started-project/getting-started-app/.env | 1 - 1 file changed, 1 deletion(-) delete mode 100644 examples/getting-started/getting-started-project/getting-started-app/.env diff --git a/examples/getting-started/getting-started-project/getting-started-app/.env b/examples/getting-started/getting-started-project/getting-started-app/.env deleted file mode 100644 index 5fec21b..0000000 --- a/examples/getting-started/getting-started-project/getting-started-app/.env +++ /dev/null @@ -1 +0,0 @@ -HS_TEST_SECRET=pears From d321f6fff87f7ebaf8083731c2ac57bd5055fa24 Mon Sep 17 00:00:00 2001 From: Byron Matto Date: Wed, 30 Oct 2024 09:09:03 -0400 Subject: [PATCH 5/6] fix module paths --- .../src/getting-started-theme/layouts/base.hubl.html | 4 ++-- .../src/getting-started-theme/weather.hubl.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/getting-started-project-theme/src/getting-started-theme/layouts/base.hubl.html b/examples/getting-started-project-theme/src/getting-started-theme/layouts/base.hubl.html index 51b7055..b770d9a 100644 --- a/examples/getting-started-project-theme/src/getting-started-theme/layouts/base.hubl.html +++ b/examples/getting-started-project-theme/src/getting-started-theme/layouts/base.hubl.html @@ -17,7 +17,7 @@
{% block header %} - {% module 'main header' path="@projects/getting-started-project/getting-started-app/components/modules/Header" %} + {% module 'main header' path="@projects/getting-started-project-theme/getting-started-theme/components/modules/Header" %} {% endblock header %} {# The main-content ID is used for the navigation skipper in the header.html file. More information on the navigation skipper can be found here: https://github.com/HubSpot/cms-theme-boilerplate/wiki/Accessibility #} @@ -26,7 +26,7 @@ {% endblock body %} {% block footer %} - {% module 'footer' path="@projects/getting-started-project/getting-started-app/components/modules/Footer" %} + {% module 'footer' path="@projects/getting-started-project-theme/getting-started-theme/components/modules/Footer" %} {% endblock footer %}
diff --git a/examples/getting-started-project-theme/src/getting-started-theme/weather.hubl.html b/examples/getting-started-project-theme/src/getting-started-theme/weather.hubl.html index bc9150e..ad1de27 100644 --- a/examples/getting-started-project-theme/src/getting-started-theme/weather.hubl.html +++ b/examples/getting-started-project-theme/src/getting-started-theme/weather.hubl.html @@ -9,7 +9,7 @@ {% module "weather" - path="@projects/getting-started-project/getting-started-app/components/modules/Weather", + path="@projects/getting-started-project-theme/getting-started-theme/components/modules/Weather", %} {% endblock body %} From a69b3811b4d53521438e20a0e4c8f85302aeb1ed Mon Sep 17 00:00:00 2001 From: Byron Matto Date: Wed, 30 Oct 2024 09:34:34 -0400 Subject: [PATCH 6/6] Update ReadME for clarity --- examples/getting-started-project-theme/README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/examples/getting-started-project-theme/README.md b/examples/getting-started-project-theme/README.md index bc53dce..39ab3c2 100644 --- a/examples/getting-started-project-theme/README.md +++ b/examples/getting-started-project-theme/README.md @@ -1,6 +1,13 @@ # Getting Started Example -The getting started example within this directory covers a variety of key features/components of working with CMS React within a HubSpot website. This guide outlines the specifics of using CMS React primitives such as Modules, Fields, and Islands, as well as integrating third-party dependencies, styling, assets, and setting up local development tooling for your project. +This example is similar to the "getting-started" example, but demonstrates how to use CMS React within a Project Theme. Project Themes allow you to build and deploy themes using the Projects framework, which enables powerful new capabilities like: + +- Using CMS React building blocks (Modules, Fields, Islands) directly within your theme +- Leveraging project-level dependencies and configuration +- Leveraging project build and deploy capabilities +- Better organization of theme assets and components + +The example shows how to structure a Project Theme, integrate React components, and take advantage of these new features while building a fully functional theme. ## Setup