- NextJS - React Framework for site builds
- CSS Modules - Component-Level CSS (aka CSS Modules) with Sass support
- Storybook - Component focused test harness for isolated component development and documentation
- next-wordpress-starter - Sample headless NextJS/WordPress project
- Patronage Headless WordPress + Next.js starter - Sample headless NextJS/WordPress project
- next/image API reference - reference on how
next/imagecomponent works to optimize images at request time - next/getStaticPaths() reference - details on routes handle pathing params and slugs
- CSS Modules reference - reference on how to use
CSS Modulesfor locally scoped CSS (used for modules) - Writing Storybook stories reference - reference on how to write stories and use arguments for stories
- WPGraphQL documentation - reference on how GraphQL works with WordPress (ex: menus)
- Use
yarn, notnpmfor installing packages and running commands - Use VSCode (so we can all leverage same plugins and ensure consistent formatting)
- Install Prettier - Code formatter plugin for VSCode and enable it so that your code reformats on save
- All modules should have Storybook stories created that demonstrate common use cases for the module
- Run
yarn installin the root - Create an
.env.localin the project root (referenceNextJS Boilerplate local .env examplein 1Password)PREVIEW_JWT- JWT token (as defined withgraphql_jwt_auth_secret_keyfilter in WordPress PHP - ref)PREVIEW_USER- WP user to use for previewing post contentPREVIEW_PASS- WP user password to use for previewing post contentPREVIEW_SECRET- Secret text validated server-side bypreview.js
If you would like to test the form component, you will need to add a local domain name to your hosts file and generate a locally signed SSL certificate to prevent the SimpleDTO script from throwing CORS errors. The SimpleDTO script is required for form prefill to function.
To enable SSL and run the server.js file:
- Add
127.0.0.1 local.tricentis.comto your hosts file- On Windows, it is located at
C:\Windows\System32\drivers\etc - On Mac, follow these instructions being sure to run
sudo killall -HUP mDNSResponderafter the changes
- On Windows, it is located at
- Create a
certificatesfolder in tricentis-frontend and cd into it. - If you are using bash or another terminal that has openssl, you can run the following command:
openssl req -newkey rsa:2048 -nodes -keyout local.tricentis.com.key.pem -x509 -days 365 -out local.tricentis.com.cert.pem - It will prompt you to enter values for various fields. All of them can be left bank except the
Common Name, which you should be assigned the value:tricentis.com. You should now have a 2 new files inside certificates. - Change directory back into the root directory, and you can now start the custom server with
node server.js(you will run this instead ofyarn run dev) - NextJs compiler and fast refresh will still work properly for development, but you will now need to use the domain name
https://local.tricentis.com:3000/when viewing your local site. (This has not been tested with the sample preview url).
| Command | Use Case |
|---|---|
yarn run dev |
run in dev mode (live refresh) |
yarn run build |
run a build |
yarn run start |
start the Node server hosting what was built |
yarn run storybook |
for isolated component level testing |
yarn run build-storybook |
build a static Storybook to storybook-static (used by Netlify build) |
NOTE:: There is no clean build command as NextJS does not use any caching between builds (as best we know).
- Theming should be set at a component levels with a class of
light-theme(default/optional),midtone-theme, ordark-theme - Atoms that require accessibility should have styles that change with a parent class of
accessibility-colors - Accessibility colors can be tested in storybook by switching between the
defaultandaccessibilethemes in the top toolbar - Accessibility can be tested in Storybook via the Accessibility tab, using addon-ally https://storybook.js.org/addons/@storybook/addon-a11y (tests can be rerun by clicking the button in the bottom right of the Accessibility panel)
REST api docs are available on a dedicated documentation multidev: https://restapi-tricentis-backend.pantheonsite.io/wp-admin/options-general.php?page=swagger-ui. Note that this is only viewable after logging into https://restapi-tricentis-backend.pantheonsite.io/editor-login.
Important: Any REST api backend updates that are made on
be-developmust be copied torestapi-tricentis-backendin order to keep documentaiton up to date.
- There is a test page
/_devthat shows some common styles - The
next/imagecomponent should be used for showing all images.- It uses a request-time optimization pattern by which the backend Node server optimizes the image at request time and caches for subsequent requests.
- Unlike Gatsby, images are not generated at build time, but request time
- NOTE: Domains must be whitelisted in
next.config.jsto allownext/imageto work for a given image url
- Adding a new language requires updates to the 'netlify-plugin-menu-json-generator-narwhal' and 'netlify-plugin-rss-xml-generator-narwhal' plugins so that it knows what languages to query for
Modules are organized in a loose atomic design structure (reference article) of atoms > molecules > modules. The simplest components are atoms, components which wrap and use atoms are molecules, and modules are components that would be put on a page.
- Clone a module folder
- Rename all references of the module name with your new module name
- Include
@import "../../../styles/baseline/_styles";in your.module.css - Define Storybook stories in
[modulename].stories.jsx
- Add new page template name in
StringConstants.js(underPageTemplates) which matches the name used in the WordPress backend - Create a new template folder in
components/page-templates(ex:TeamMemberArchvieTemplate) and create the corresponding.jsxand.module.scssfiles - Build out the page template referencing other page templates
- Edit
PageTemplateSelector.jsxto return the new template component when the page.template matches - Edit
[...slug].jsingetStaticPaths()to indicate that it knows how to handle the new template (referencing it's StringConstants name) - Edit
wplib/pages.getPageTemplateDataByDatabaseID()to use a graphql query for the page template
We have a Netlify plugin we have created (/plugins/netlify-plugin-redirects-narwhal) that queries for all redirects (from the Redirection WordPress plugin (and its corresponding GraphQL plugin)) and pushes them into Netlify's collection of redirects for a deployment.
When maintaining this plugin, you will want to add the following to your netlify.toml so that you can test the plugin locally with netlify start:
[[plugins]]
package = "@netlify/plugin-nextjs"
[build]
command = "yarn build"
publish = ".next"
These changes (^) are not included in the netlify.toml on Netlify as they will override the build settings for our builds, and break our Storybook builds which use a different build command and publish folder, and don't use the NextJS Netlify plugin.
Preview works by directing the user to an /api/preview/ route passing along the id of the page as well as a secret (which must match PREVIEW_SECRET as defined in environment variables). So long as the NextJS server is running, the /api/preview/ endpoint will verify the secret, make sure the page exists, authenticate as a user to generate a bearer token, and then redirect to the proper page URL passing along two cookies (__prerender_bypass and __next_preview_data) that indicate preview mode is on, and to get revisions in the REST call to get the latest preview data.
References:
- Run
yarn run devlocally - Visit a sample page preview url (ex:
// http://localhost:3000/api/preview?secret=[PREVIEW_SECRET]&id=3093&type=postType&typeValue=page- replacing[PREVIEW_SECRET]with environmentPREVIEW_SECRET) - Visit a sample CPT preview url (ex:
http://localhost:3000/api/preview?secret=[PREVIEW_SECRET]&id=1395&type=postType&typeValue=case_study- replacing[PREVIEW_SECRET]with environmentPREVIEW_SECRET)
- Create a new backend multi-dev instance
- Create a new frontend code branch with your preview changes
- Setup a new Netlify Site configured to build using the new backend endpoint and building your frontend branch
- Update the Jamstack plugin settings on the new backend multi-dev instance to point to your front-end branch's preview api route (/api/preview)
NOTE:: Configuring a new Netlify instance is needed so that the environment can point to the proper backend you are testing with
- Previewing of some forms (ex: Preference Center) do not look correct as the logic is based on the url ending in /preference-center (which will not be the case for a preview)
wp-graphqldoes not respond properly with preview data if the data is queried byslugoruri- the data must be queried bydatabase idorid. (github issue reference)- NOTE: The current WP preview plugin we are using uses database id (ex:
2) instead of id (ex:cG9zdDoy), which is why we are querying by database id currently (seeTODO itemsitem about potentially switching away from database id)
- NOTE: The current WP preview plugin we are using uses database id (ex:
- Querying for SEO data in a preview request throws errors, so we use a different query for preview just for that (ref:
QUERY_PAGE_BY_IDvsQUERY_PAGE_BY_ID_WITH_SEO)
- Component doesn't show within Storybook, but no build errors?
- Check the console out put for Storybook in a browser - likely showing a runtime error (ex: test stories aren't setting test cases well (ex: name of story variable not consistent between creating it and setting its args)
- Rendering a page gives an Internal Server Error 500
- Typically a bad GraphQL query - try to run the query manually in GraphiQL in wp-admin
rem-calcmethod not turning intoremunits at runtime (ex: Developer Tools showsrem-calc(16)instead of1 rem)- Make sure you are importing
_stylesin your module
- Make sure you are importing
- Build fails with
Error: Cannot query field "seo" on type "Page".- The WordPress backend does not have
YoastandWPGraphQL Yoast SEO Addonplugins installed
- The WordPress backend does not have
- Storybook build is failing due to file being unable to resolve in scss?
- Make sure to add an alias to that file in
.storybook/main.js
- Make sure to add an alias to that file in
-
WPGraphQL limits responses to only 100 items without changing
graphql_connection_max_query_amountbackend value. Currenlty this is set to 3000 on the backend (so we can query for all redirects - up to 3000). Should consider implementing paged requests when needing to get all items of a given type. (task TR2-79) -
Querying by uri with WPGraphQL does not work for custom post types when used in tandem with WPML. For example, we cannot directly query for a case study by uri - it will return null even though the uri is valid. As such we have to instead query for a listing of all case studies and find the matching id based on uri by ourselves. Ref: KI-WPML-URI-ISSUE [NOTE:: See UPDATE below as this is no longer an issue persay, but an intentional decision]
- UPDATE: Because of Netlify issue number 1179 (Github reference), having
fallbackset tofalse(like we have) is not preventing paths (which aren't in the paths returned fromGetStaticPaths) being 404'd properly. As such, whatever URL routes that hit[[...slug]].jsare attemped to be generated at request time. If it werent for this KI-WPML-URI-ISSUE issue, those bad paths would be passed to a direct backend query, which could open a path for an injection attack. As such, KI-WPML-URI-ISSUE is considered a good thing (and an approach we want to stick with) as looking up all valid URLs and comparing them prevents potential injection attacks VS if we were querying the url passed into the route directly. - Example of unworking query:
query McKessonByUriQuery { caseStudy(id: "/fr/case-studies/mckesson/", idType: URI) { id databaseId title slug uri locale { locale } } } - UPDATE: Because of Netlify issue number 1179 (Github reference), having
-
See
Known issuesinHow preview workssection.
- Address
TODO::items (in comments of code) - Fix needing two queries per page (one to get
databaseIdfrom slug/uri, the other to get data bydatabaseId)- Known issue with
wp-graphqlpreventing querying of preview data by slug (ref) - Fixing this would prevent needing two queries per page
- Known issue with
- Switch back to ids and not database IDs?
- Preview plugin currently uses database id (ex:
2) instead of post ids (ex:cG9zdDoy), so keeping with database ids until a different preview plugin is in place
- ongoing - initial sprint 1 work
- 2022/02/20 - Initial creation of Tricentis codebase
- 2022/02/20 - Initial release to master (boilerplate)