diff --git a/packages/react-server/CHANGELOG.md b/packages/react-server/CHANGELOG.md
index cfd58c85d6..9c447a567d 100644
--- a/packages/react-server/CHANGELOG.md
+++ b/packages/react-server/CHANGELOG.md
@@ -7,6 +7,12 @@ and adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
+## 0.2.0
+
+### Changed
+
+- `createRender` now passses two arguments, the first of which is an unchanged `Koa.Context` object, the second containing `react-server` specific derived data, such as `locale`.
+
## [0.1.5] - 2019-08-18
- logger middleware will fallback to `console` in render middleware
diff --git a/packages/react-server/README.md b/packages/react-server/README.md
index f3f0b0f3a7..ad82b51d92 100644
--- a/packages/react-server/README.md
+++ b/packages/react-server/README.md
@@ -31,11 +31,11 @@ To begin using this package, Node apps only require a server entry point that ca
```
import React from 'react';
-import {createServer, RenderContext} from '@shopify/react-server';
+import {createServer, Context} from '@shopify/react-server';
import App from '../app';
const app = createServer({
- render: (ctx: RenderContext) =>
+ render: (ctx: Context) =>
});
```
diff --git a/packages/react-server/src/index.ts b/packages/react-server/src/index.ts
index b70daa35f6..b13f165077 100644
--- a/packages/react-server/src/index.ts
+++ b/packages/react-server/src/index.ts
@@ -1,3 +1,3 @@
export {createServer} from './server';
-export {createRender, RenderContext} from './render';
+export {createRender, Context} from './render';
export {createLogger} from './logger';
diff --git a/packages/react-server/src/render/index.ts b/packages/react-server/src/render/index.ts
index 8a68cdb1ad..0e99c059eb 100644
--- a/packages/react-server/src/render/index.ts
+++ b/packages/react-server/src/render/index.ts
@@ -1 +1 @@
-export {createRender, RenderContext, RenderFunction} from './render';
+export {createRender, Context, RenderFunction} from './render';
diff --git a/packages/react-server/src/render/render.tsx b/packages/react-server/src/render/render.tsx
index 8af1d34122..8d4de1421a 100644
--- a/packages/react-server/src/render/render.tsx
+++ b/packages/react-server/src/render/render.tsx
@@ -21,13 +21,13 @@ import {Header, StatusCode} from '@shopify/react-network';
import {getAssets} from '@shopify/sewing-kit-koa';
import {getLogger} from '../logger';
-export type RenderContext = Context & {
- locale: string;
-};
-export type RenderFunction = (ctx: RenderContext) => React.ReactElement;
+export {Context};
+export interface RenderFunction {
+ (ctx: Context, data: {locale: string}): React.ReactElement;
+}
export function createRender(render: RenderFunction) {
- return async function renderFunction(ctx: RenderContext) {
+ return async function renderFunction(ctx: Context) {
const logger = getLogger(ctx) || console;
const assets = getAssets(ctx);
const networkManager = new NetworkManager();
@@ -37,7 +37,7 @@ export function createRender(render: RenderFunction) {
const locale = Array.isArray(acceptsLanguages) ? acceptsLanguages[0] : 'en';
try {
- const app = render({...ctx, locale});
+ const app = render(ctx, {locale});
await extract(app, {
decorate(app) {
return (
diff --git a/packages/react-server/src/render/test/render.test.tsx b/packages/react-server/src/render/test/render.test.tsx
index dd73b6b681..7259f6580f 100644
--- a/packages/react-server/src/render/test/render.test.tsx
+++ b/packages/react-server/src/render/test/render.test.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import {createMockContext} from '@shopify/jest-koa-mocks';
import withEnv from '@shopify/with-env';
-import {createRender, RenderContext} from '../render';
+import {createRender} from '../render';
jest.mock('@shopify/sewing-kit-koa', () => ({
getAssets() {
@@ -24,11 +24,24 @@ describe('createRender', () => {
const ctx = createMockContext();
const renderFunction = createRender(() => <>{myCoolApp}>);
- await renderFunction(ctx as RenderContext);
+ await renderFunction(ctx);
expect(ctx.body).toContain(myCoolApp);
});
+ // we cannot test this with `createMockContext` because it actually clobbers the proxy methods itself :(
+ // eslint-disable-next-line jest/no-disabled-tests
+ it.skip('does not clobber proxies in the context object', async () => {
+ const headerValue = 'some-value';
+ const ctx = createMockContext();
+ ctx.set('some-header', headerValue);
+
+ const renderFunction = createRender(ctx => <>{ctx.get('some-header')}>);
+ await renderFunction(ctx);
+
+ expect(ctx.body).toContain(headerValue);
+ });
+
it('in development the body contains a meaningful error messages', () => {
withEnv('development', async () => {
const ctx = {...createMockContext(), locale: ''};