Atlassian Connect Express with REACT framework

Hello everyone, I am developing an ACE cloud addon in Node.js, and I don’t want to use a handlebars as a template view, instead I want to use REACT. The outputted REACT files are added to the public/ directory of the ACE template. When I try to call the route

app.get('/render/config', (req, res) => {
res.sendFile(path.join(__dirname, '/public/index.html'));

the content is rendering to the specified route on localhost, but not when is applied on the cloud instance -I get response failed to load response data). So my basic question is what am I missing in the configuration, or how can I combine actually the REACT app with the ACE?

You could simply use the default handlebar template to include the script, it works basically the same way.

I used a custom webpack configuration for this, can’t speak for create-react-app or anything else

Thank you for the response, can you tell me more details on this? Where is the default handlebar template?

You could fine them here under views for example

@ernst.stefan Thank you but still I can’t understand how can I include the build file (REACT), into the script?


Here’s how I am using it. Maybe this will help you. Note: in this example I am using Handlebars for layout and React for views, where sources are separate from compiled files.


import express from 'express';
import ace from 'atlassian-connect-express';
import hbs from 'express-hbs';

import routes from './routes.js'; // see below
app.locals.config = {
  views: './views',
  modules: './node_modules',
  public: './public',
  uri: '/'
// Configure Handlebars view engine
app.engine('hbs', hbs.express4({ partialsDir: app.locals.config.views }));
app.set('view engine', 'hbs');

// Configure views location (see
app.set('views', app.locals.config.views);

// Bootstrap atlassian-connect-express (ace)
const addon = ace(app);
// Mount static resource dirs
// Anything in ./public and ./node_modules will be served up as static content
app.use(app.locals.config.uri, express.static(app.locals.config.public));
app.use(app.locals.config.uri, express.static(app.locals.config.modules));

// Wire up routes using the express and `atlassian-connect-express` objects
const router = express.Router();
routes(router, addon);

// Attach and use loaded routes on application URI path
app.use(app.locals.config.uri, router);


<!doctype html>
  <meta charset="utf-8">
  <script src="{{hostScriptUrl}}" type="text/javascript" data-options="sizeToParent:true"></script>
  <!-- here include global scripts/styles -->




  <!-- here include view specific scripts -->
  <div id="container" />


export class ContainerApp extends React.Component {
  constructor(props) {

  componentDidMount() {

  render() {

ReactDOM.render(<ContainerApp />, document.getElementById('container'));


export default function routes(router, addon) {
    router.get('/container', addon.authenticate(), (req, res) => {
        res.render('container', {
            title: 'Container App',

With above in place you can keep your React sources in ./src, where before each launch you will need to compile them into ./public using something like npx babel --out-dir ./public --copy-files ./src (e.g. add ‘build-src’ to scripts in your package.json, then you can execute npm run build-src).

During development you could ‘watch’ the sources and update on changes with npx babel --watch ./src --out-dir ./public --copy-files (e.g. add as ‘watch-src’ to scripts in your package.json, then you can execute npm run watch-src in a separate process).

1 Like