Signpost Template
This repository is the website template for creating new Signpost instances.
This README pertains to working with this repository as a template for new
instances. There's also README-SITE.md
that describes how to operate a site
created from this template.
Instructions for setting up a new Signpost instance
1. Fork the repository
2. Swap README
- Delete this README and rename
README-SITE.md
toREADME.md
. - Fill out TODOs in
README.md
.
3. Run the new site's development set up instructions
4. Choose your site's content structure
- Use Figma guidelines to decide which content structure the site should follow: Beporsed or UFU.
- Set
USE_CAT_SEC_ART_CONTENT_STRUCTURE
inlib/constants.ts
accordingly. - If you have chosen U4U:
- [Optional] Delete the category page file. It's not present in this content structure.
5. Customize your site
- Fill out the environment variables documented in
README-SITE.md
.- Add all variables to .env.local.
- Provide some environment variables (
ZENDESK_URL
andZENDESK_OAUTH_TOKEN
) as repository secrets.
- Provide the site's constants. Search for TODOs.
- Finish TODOs in lib/translations.tsx.
- Note: Create new Dynamic content on Zendesk with your website's name in prefix
- Finish TODOs in lib/social-media.tsx.
- Note: you might need to change Social media logo images in public/ directory
- Create Algolia Search indexes for Zendesk Articles and Search queries, and replace indexes in lib/constants.ts.
- Follow Search documentation on how to create new index.
- Fill out custom CSS variables in next.config.js.
- Provide the site's logo in lib/logo.ts.
- Enable Service map by completing TODO in lib/constants.ts
- Enable Chat widget by completing TODO in pages/_document.tsx
6. Connect the site to Vercel
The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.
Check out Next.js deployment documentation for more details.
7. Setup a domain
- Set up the target domain after you have set up the site in the previous steps by following https://vercel.com/docs/concepts/projects/custom-domains.
- Remove Host mapping from Zendesk for your brand: https://signpost-global.zendesk.com/admin/account/brand_management/brands.
- It's needed to allow Zendesk Admin functionalities (e.g., category editing and article preview) to keep working through Zendesk Themes.
- Verify that editing category name in Zendesk still works for your brand.
8. Set up Google Analytics
Create a GA4 Property and find your Measurement ID
If you already have a Google Analytics Measurement ID (i.e. G-XXXXXXXXX or UA-XXXXXXXXX), you can skip this step.
To set up Google Anaytics, you will first need to follow the online instructions in order to create a new Google Analytics 4 property and add a data stream. After this, find your Measurement ID.
Set up your app to collect data
To start data collection, you will need to add your Google Analytics ID(s) to
your local .env.local
file and as environment
variables in
your vercel project settings, using the NEXT_PUBLIC_*
notation. For example,
if you had a Universal Analytics ID and a Google Analytics 4 ID, you could have
the corresponding environment variables: NEXT_PUBLIC_GA_ID
and
NEXT_PUBLIC_GA4_ID
. You may have two IDs, for example, during the
migration from Universal Analytics to Google Analytics
4.
Next, ensure that these environment variables are included in the GOOGLE_ANALYTICS_IDS
variable of the the site's constants. For example,
export const GOOGLE_ANALYTICS_IDS = [
process.env.NEXT_PUBLIC_GA_ID ?? '',
process.env.NEXT_PUBLIC_GA4_ID ?? '',
];
These Measurement IDs are connected to the site by using the Analytics
component from @ircsignpost/signpost-base/dist/src/analytics
in your app's pages/_app.tsx
file.
This component needs to be added as close to the top as possible (above
<Component {...pageProps} />
). Your file should look something like the
following:
...
import Analytics from '@ircsignpost/signpost-base/dist/src/analytics';
import { GOOGLE_ANALYTICS_IDS } from '../lib/constants';
...
function MyApp({ Component, pageProps }: AppProps) {
return (
<>
<Analytics googleAnalyticsIds={GOOGLE_ANALYTICS_IDS}/>
<Component {...pageProps} />
</>
);
}
export default MyApp;
Now your app should be setup to start collecting data!
Tracking Events
By default, the Analytics
component tracks page views for you, but you may want to track other events such as page clicks, or maybe disable/enable analytics depending on a user's response to a cookie banner (consider using @ircsignpost/signpost-base/dist/src/cookie-banner
). In order to do this, there are a couple lightweight utility functions you can use.
NOTE: These functions only work if you have successfully set up and began using the Analytics
component.
// Opts user out of Google Analytics tracking.
export function disableGoogleAnalytics(googleAnalyticsIds: string[]);
// Re-enables Google Analytics tracking if it was previously disabled.
export function enableGoogleAnalytics(googleAnalyticsIds: string[]);
// Tracks a click event for the given category and label.
export function trackClickEvent(eventCategory: string, eventLabel: string);
9. Generate Zendesk OAuth token for your site
You need to generate a new Zendesk OAuth token for your site for Zendesk logging and API usage tracking purposes. To do that, you need full Admin access. If you don't have it, ask your Product manager (Liam) to generate it for you with following instructions:
- Add a new OAuth client in Zendesk Admin center: https://signpost-global.zendesk.com/admin/apps-integrations/apis/zendesk-api/oauth_clients
- Find ID of your new Oauth client: https://signpost-global.zendesk.com/api/v2/oauth/clients.json
- Copy number from ‘id’ field corresponding to the new client you added
- Perform the following command in the terminal
curl https://signpost-global.zendesk.com/api/v2/oauth/tokens.json -H "Content-Type: application/json" -d '{"token": {"client_id": <new_oauth_client_id>, "scopes": ["read"]}}' -X POST -v -u <your_email>/token:<api_token>
- Substitute <new_oauth_client_id>, <your_email> and <api_token>
- Get an API token from https://signpost-global.zendesk.com/admin/apps-integrations/apis/zendesk-api/settings/tokens/
10. Setup Next.js preview
If you have followed the steps in this README, you've already generated a value for PREVIEW_TOKEN
environment variable, provided it in Vecel (here) and added the preview logic to your website (thanks to the preview logic in the Article component). That already allows you to access preview mode manually.
See defenition and manual usage of preview mode.
To additionaly enable the Next.js preview for the ZD content editor links:
-
(Optional but recommended) For Next.js-based Signpost instances ZD theme is kept alive only for preview mode and category/section edits. So to avoid confusion between the live Next.js website and the ZD theme, replace the ZD theme of your instance with a version of Copenhagen theme where all not required
.hbs
files, styles, translations are removed and the required.hbs
templates contain something like<!-- This file needs to exist when importing Zendesk theme. -->
. -
Edit your ZD theme's source code
-
Replace the content of
article.hbs
with<div> <div id="article-container"> <p>Redirecting...</p> </div> <script> // The script below implements Next.js preview mode redirects. More details in: // https://docs.google.com/document/d/1IbtY_EvIm0c1C8yeKpEPWwPvWJyHiNehYkRpVJJ65kg const baseUrl = `{{ settings.preview_base_url }}`;; const locale = `{{ help_center.locale }}`; const articleId = `{{ article.id }}`; const previewToken = `{{ settings.preview_access_token }}`; // Example ZD preview URL: // https://signpost-u4u.zendesk.com/hc/en-us/articles/4810103030679/preview/eyJhbGciOiJIUzI1NiJ9.eyJpZCI6NDgxMDEwMzAzMDY3OSwiZXhwIjoxNjYzOTQ2ODk3fQ.YlBI8yUJaJVe8nI3_o1kRrtk_0eomhe3jGL2JR-G4og const isPreviewMode = window.location.href.split('/').includes('preview'); // URLs are constructed based on the routing from https://github.com/unitedforukraine/signpost-template const nextjsPreviewUrl = `${baseUrl}/api/preview?slug=/${locale}/articles/${articleId}&secret=${previewToken}`; // Clears preview cookie if it was set, then redirects to the live website in normal mode. const nextjsUrl = `${baseUrl}/api/clear-preview-cookies?slug=/${locale}/articles/${articleId}`; window.location.replace(isPreviewMode ? nextjsPreviewUrl : nextjsUrl); </script> </div>
-
Addd two parameters to
manifest.json
's settings array:preview_access_token
andpreview_base_url
underpreview_access_token_group_label
label"settings": [ { "label": "preview_access_token_group_label", "variables": [ { "identifier": "preview_access_token", "type": "text", "value": "", "label": "preview_access_token_label", "description": "preview_access_token_description" }, { "identifier": "preview_base_url", "type": "text", "value": "", "label": "preview_base_url_label", "description": "preview_base_url_description" } ] } ]
-
-
Upload the edited theme as set it as live in Zendesk UI
-
Provide the values for
preview_access_token
(the preview access token value that you've generated earlier) andpreview_base_url
(the domain name of your instance, e.g. https://www.unitedforukraine.org/) in the theme's UI: click Customize on the live theme -> click onpreview_access_token_group_label
group -> paste the values -> click Publish -
(Optional): educate your content writers on how to access preview mode manually and in the ZD UI
PWA and Offline availability
Next.js supports PWA adding the next-pwa plugin.
To install the plugin, just use:
yarn add next-pwa
And then you should update your next.config.js
file to use the plugin. Example:
const withLess = require('next-with-less')
const withPWA = require('next-pwa')({ dest: 'public' })
const nextConfig = {
...
}
module.exports = withPWA(withLess({
...nextConfig,
lessLoaderOptions: {...},
}))
Please refer to the next-pwa site for more information and extra configurations.
Rollback from Vercel
All the deployments are controled through the Vercel deploy site, so if anything wrong happens with a deploy we can just move to production the last succesfull deploy
We need to go to Vercel and select the instance that we need to fix
After doing this we have to go to the Deployments
tab and find the latest succesfull one.
Once finded we only need to click the three dots on the right of the deploy and click on the Promote to production
option.
This will trigger a redeploy of the instance with the code of the deploy selected so we can have an instance running with no problems in production while we debug the issue with the latest code pushed.
Additional data:
- Name branching: all the branches should be descriptive of what the changes are and should contain the number of the task from Jira, for e.g. if I'm pushing some style changes on footer the branch should be named something along "sp-123-footer-styles-modifications"
- How we track feat updates: All the PRs should follow the Conventional Commit Messages
- The most important prefixes you should have in mind are:
-fix
: which represents bug fixes.
-feat
: which represents a new feature.
- The most important prefixes you should have in mind are:
- How to ensure that rollback is going to a correct production branch: we only have one production branch per project so this is not an issue.
Architectural Decisions
Dual content structure
There are two possible versions of content in a Zendesk instance. They are both explained at Figma.
The components signpost-base work with both of them. During setting up of this template, you'll do steps to configure the site for a specific version. (TODO: #103)