TerriaJS Server
TerriaJS-Server is a foundational Node.js Express server designed to complement the TerriaJS geospatial platform. It provides essential backend services for web-based 2D and 3D geospatial data explorers, including a robust CORS proxy for accessing data providers that lack proper CORS headers, a `proj4` Coordinate Reference System (CRS) lookup service, an `ogr2ogr` conversion service for unsupported geospatial vector data formats (like shapefiles) to GeoJSON, and services for persistent sharing of map configurations. Currently at stable version 4.0.4, published recently, the package undergoes active maintenance with updates driven by the needs of the broader TerriaJS ecosystem. Its key differentiators lie in its specialized geospatial services and deep integration with TerriaJS and TerriaMap, enabling rich, interactive mapping applications, particularly within the context of National Map projects.
Common errors
-
ERR_REQUIRE_ESM: require() of ES Module ...terriajs-server/lib/app.js from ... not supported.
cause Attempting to use `require()` to import `terriajs-server`, which is an ECMAScript Module (ESM) since version 4.0.0, in a CommonJS context.fixChange your import statement to use ESM syntax: `import { createTerriaServer } from 'terriajs-server';` or `import createTerriaServer from 'terriajs-server';` if it's a default export. -
Failed to start TerriaJS Server: Error: The "config.json" file does not exist. Please create one.
cause The server failed to find its essential configuration file, `serverconfig.json`, at the expected location.fixCopy `serverconfig.json.example` (or `devserverconfig.json`) from the package's root or documentation to `serverconfig.json` in your project's root and configure it according to your needs. Ensure the server has read access to this file. -
CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
cause Despite `terriajs-server` providing a CORS proxy, this error indicates the requested domain for proxying is not allowed by the server's configuration.fixEdit your `serverconfig.json` file and add the domain of the problematic resource to the `allowProxyFor` array. Ensure the URL scheme (HTTP/HTTPS) and domain exactly match. -
Error: Port 3001 is already in use
cause Another process is already using the default port (3001) that `terriajs-server` attempts to bind to.fixChange the `port` in your `serverconfig.json` or pass the `--port` option when starting the server (e.g., `npm start -- --port 8000`) to use an available port. Kill the conflicting process if it's unintentional.
Warnings
- breaking TerriaJS-Server now requires Node.js version 20.0.0 or higher (for v4.x) and 22.0.0 or higher (for v5.x-alpha). Running with older Node.js versions will result in errors.
- breaking The package has transitioned to an ESM-first module. CommonJS `require()` statements for the main package entry point will no longer work, leading to `ERR_REQUIRE_ESM` errors.
- breaking PM2 is no longer officially supported for running `terriajs-server`, and the default `npm start` script now runs the server in the foreground. Existing PM2 configurations may need adjustment or replacement.
- gotcha Default proxy domains in `serverconfig.json` are largely deprecated and will be removed in future releases. Relying on these pre-configured domains without explicit custom configuration is risky.
- breaking Security vulnerabilities in the proxy endpoint (CVEs) have been addressed by replacing `express-brute` with `rate-limiter-flexible` and fixing a bug that allowed requests to unintended domains.
Install
-
npm install terriajs-server -
yarn add terriajs-server -
pnpm add terriajs-server
Imports
- createTerriaServer
const createTerriaServer = require('terriajs-server');import { createTerriaServer } from 'terriajs-server'; - startServer
import { startServer } from 'terriajs-server';import 'terriajs-server/terriajs-server.js';
- ServerConfig
import { ServerConfig } from 'terriajs-server';import type { ServerConfig } from 'terriajs-server';
Quickstart
import express from 'express';
import path from 'path';
import { createTerriaServer } from 'terriajs-server';
// Minimal server configuration - typically read from serverconfig.json
const serverConfig = {
port: process.env.PORT ?? 3001,
public: true,
// Define allowed domains for the proxy, crucial for security
allowProxyFor: [
'https://example.com',
'https://another-domain.org'
],
// Optional: Share service configuration (e.g., Gist, S3)
share: {
type: 'gist',
accessToken: process.env.GITHUB_GIST_TOKEN ?? '' // Required for Gist
},
// Other TerriaJS-Server specific configurations go here
};
async function startCustomTerriaServer() {
try {
// createTerriaServer returns an Express application instance
const app = await createTerriaServer(serverConfig);
// Serve static files from a 'wwwroot' directory (e.g., where TerriaMap is built)
const wwwrootPath = process.env.WWWROOT_PATH ?? path.join(process.cwd(), 'wwwroot');
app.use(express.static(wwwrootPath));
app.listen(serverConfig.port, () => {
console.log(`TerriaJS Server listening on port ${serverConfig.port}`);
console.log(`Serving static files from: ${wwwrootPath}`);
});
} catch (error) {
console.error('Failed to start TerriaJS Server:', error);
process.exit(1);
}
}
startCustomTerriaServer();