App Config
Never import configs from @traveloka/core/config in your app code. Use either getPublicRuntimeConfig or getServerRuntimeConfig as explained below.
Using App Config
By default, we provide a predefined set of runtime config that you can use "in the server" (only) or "publicly" (in the server and the client). The way you use it depends on where the specific code is executed. Sensitive values should only be stored in server configs.
We're using next.js built-in config mechanism for this, this means that the naming convention and how to extend it is more-or-less the same.
Public runtime config
Public runtime config is available on the server and on the client-side. It will be dumped to the client-side.
import { getPublicRuntimeConfig } from '@traveloka/core';
function Component() {
const config = getPublicRuntimeConfig();
return (
<Button
onPress={() => {
console.log(config.url.desktopHost);
}}
/>
);
}
Server runtime config
You should be really careful and know what you're doing when using serverRuntimeConfig because you might expose sensitive information to users (either through JS bundle, or hydrated JSON data). There are 2 safe ways to access serverRuntimeConfig:
- The first one is when you have a custom
_document. - The second one is done by creating 2 files: one of which using the
.client.tsxextension. (Basically, using the client extension allow you to separate the logic between server and client.)
import { getServerRuntimeConfig } from '@traveloka/core';
function ServerComponent() {
const config = getServerRuntimeConfig();
// do something with config
}
Extending Config
You can extend our config the same way you extend Next.js config.
The standard method
First add either serverRuntimeConfig or publicRuntimeConfig in your next.config.js and you can use it in your app immediately.
// [product]/app-desktop/next.config.js
const nextConfig = {
publicRuntimeConfig: {
myKey: 'myValue',
},
};
module.exports = withTravelokaConfig(nextConfig);
Differentiating values based on the environment
If you need the value to be different based on different environment values, you can use values from @traveloka/core/config:
// [product]/app-desktop/next.config.js
const globalConfig = require('@traveloka/core/config');
const nextConfig = {
publicRuntimeConfig: {
uploadUrl: globalConfig.url.upload.external,
},
};
module.exports = withTravelokaConfig(nextConfig);
How the merging works
If you're wondering how the merge is performed, we're using merge-options internally with concatArrays and ignoreUndefined options enabled. If you want to disable it or configure how the merge is performed, you can add mergeOptionsConfig field in your next.config.js:
const globalConfig = require('@traveloka/core/config');
const nextConfig = {
mergeOptionsConfig: {
ignoreUndefined: false,
concatArrays: false,
},
publicRuntimeConfig: {
uploadUrl: globalConfig.url.upload.external,
},
};
module.exports = withTravelokaConfig(nextConfig);
Fixing the type.
As you might know all app code are strictly typed, including config. When you import publicRuntimeConfig or serverRuntimeConfig without any modification you'll get an error when accessing your custom config.
The solution here is to create your config type yourself (the convention is to use types.ts in root), and use the TypeScript as operator:
// file: type.ts
import { PublicRuntimeConfig } from '@traveloka/core';
export interface YourPublicConfig extends PublicRuntimeConfig {
uploadUrl: string;
}
And then use this in your app code:
import { publicRuntimeConfig } from '@traveloka/core';
import { YourPublicConfig } from './types';
const config = publicRuntimeConfig as YourPublicConfig;
console.log(config.uploadUrl);
You can also re-export the config into a separate module in your common packages, so instead of importing from @traveloka/core, you import publicRuntimeConfig from @traveloka/xxx-common.
Remember to be mindful about sensitive information that might be exposed through config.