Utilizing Webpack and Create React App with Zendesk’s Custom Pages

Greg Katechis
Zendesk Developer Blog
3 min readApr 1, 2022

--

This article is part of a wider family of articles exploring Zendesk custom pages. You can find out more about other technologies we used and their implementations into custom pages in this article.

For this project, we wanted to build a basic single page React app that could live on a custom page in Zendesk Guide, using Tailwind to style the frontend. To do this, we’ll need to use webpack in order to compile our code into a single file that we can upload as an asset in Guide and then reference that asset from the custom page in order to run the app.

How to get webpack working with custom pages

I’m going to assume that you have webpack installed and configured based on your project’s needs. If not, I recommend walking through webpack’s documentation on the topic. There is a lot of info there and it’s not laid out in a clearly linear A-B manner, so if this is your first time with webpack, I recommend searching Google for “webpack + [your stack]” to see how to best set it up.

  • If you don’t already have a config file for webpack, navigate to your project root and create it and then open it.
touch webpack.config.js

Our project is using Typescript, so we need to use a loader, specifically ts-loader. We’re also resolving .ts and .tsx extensions, so if you’re not using Typescript, I’d follow webpack’s docs for configuration. Basically, this may not be the exact config that you’ll use for your project

  • The important part of the config here is the LimitChunkCountPlugin (link to docs), which allows you to define the maximum number of chunks that a build will contain. When you use this option, you’ll get one .js file, which is exactly what we want.
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const devMode = process.env.NODE_ENV !== 'production';
const webpack = require('webpack');
module.exports = {
entry: './src/index.tsx',
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
{
test: /\.(ts|tsx)$/,
exclude: /node_modules/,
loader: 'ts-loader',
},
{
test: /\.css$/i,
use: [
devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
],
},
],
},
plugins: [
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 1,
}),
],
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
};
  • Since we can’t upload a source map, we don’t need a source map, why waste build time generating it? Navigate to your package.json and under "scripts": "build": add GENERATE_SOURCEMAP=false. Here’s an example in my project, yours may look different:
...
"scripts": {
"start": "react-scripts start",
"build": "GENERATE_SOURCEMAP=false webpack build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
...

Now when you run npm run build, you should see a new folder called “dist” appear at the root of your project. There will be a file called bundle.js (unless you used a different name), that contains your code, your css, and your media. We’ll use that in the next part.

Getting the app into custom pages

Alright, we’ve got our build done, now we need to get this working in custom pages.

  • Navigate to edit your code in Guide by going to “Guide Admin” >> “eye” icon (customize design) on left sidebar >> “Customize” (for your selected theme) >> “Edit code” >> “Add” drop-down >> “Custom page”
  • Give your page a name and accept/change the URL >> “Add custom page”
  • You can use your own boilerplate or use the following gist (slightly modified from CRA’s index.html), which will have the asset placeholder ready for you. If you use your own html file, you can use line 15 below to add your js to the page.
  • Upload the bundle from your build >> static >> jsand build >> static >> css as assets via “Add” >> “Asset”
  • Now all you need to do is click on the asset and you’ll see three options. We want the one from the bottom “Javascript (via template)” and copy/paste just the asset portion of that into the appropriate parts of line15. You’re all done!

Congrats, you’ve successfully taken your React app and bundled into a single file that you can serve in custom pages! If you run into any issues with this, drop a comment below!

--

--