react-dom/server#renderToString JavaScript Examples
The following examples show how to use
react-dom/server#renderToString.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: server.js From ReactCookbook-source with MIT License | 6 votes |
server
.disable('x-powered-by')
.use(express.static(process.env.RAZZLE_PUBLIC_DIR))
.get('/*', (req, res) => {
const context = {};
const markup = renderToString(
<StaticRouter context={context} location={req.url}>
<App />
</StaticRouter>
);
if (context.url) {
res.redirect(context.url);
} else {
res.status(200).send(
`<!doctype html>
<html lang="">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta charset="utf-8" />
<title>Welcome to Razzle</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
${cssLinksFromAssets(assets, 'client')}
</head>
<body>
<div id="root">${markup}</div>
${jsScriptTagsFromAssets(assets, 'client', ' defer crossorigin')}
</body>
</html>`
);
}
});
Example #2
Source File: server.js From merkur with MIT License | 6 votes |
export function createWidget(widgetParams) {
return createMerkurWidget({
...widgetProperties,
...widgetParams,
$dependencies: {
render: renderToString,
},
async mount(widget) {
const { View, slot = {} } = await viewFactory(widget);
return {
html: widget.$dependencies.render(View(widget)),
slot: Object.keys(slot).reduce((acc, cur) => {
acc[cur] = {
name: slot[cur].name,
html: widget.$dependencies.render(slot[cur].View(widget)),
};
return acc;
}, {}),
};
},
});
}
Example #3
Source File: RoutePublic.spec.js From full-stack-fastapi-react-postgres-boilerplate with MIT License | 6 votes |
describe('modules/RoutePublic', () => {
it('should render the Login component for unauthenticated access', () => {
const render = renderToString(
<Router initialEntries={['/login']}>
<RoutePublic
exact
path="/login"
component={() => <div>LOGIN</div>}
isAuthenticated={false}
/>
</Router>,
);
expect(render).toMatchSnapshot();
});
it('should redirect to /private for authenticated access', () => {
const render = renderToString(
<Router initialEntries={['/login']}>
<RoutePublic
exact
path="/login"
component={() => <div>LOGIN</div>}
isAuthenticated={true}
/>
</Router>,
);
expect(render).toMatchSnapshot();
});
});
Example #4
Source File: RoutePrivate.spec.js From full-stack-fastapi-react-postgres-boilerplate with MIT License | 6 votes |
describe('modules/RoutePrivate', () => {
it('should redirect for unauthenticated access', () => {
const render = renderToString(
<Router initialEntries={['/private']}>
<RoutePrivate
exact
path="/private"
component={() => <div>PRIVATE</div>}
isAuthenticated={false}
/>
</Router>,
);
expect(render).toMatchSnapshot();
});
it('should allow navigation for authenticated access', () => {
const render = renderToString(
<Router initialEntries={['/private']}>
<RoutePrivate
exact
path="/private"
component={() => <div>PRIVATE</div>}
isAuthenticated={true}
/>
</Router>,
);
expect(render).toMatchSnapshot();
});
});
Example #5
Source File: RoutePublic.spec.js From full-stack-fastapi-react-postgres-boilerplate with MIT License | 6 votes |
describe('RoutePublic', () => {
it('should render the Login component for unauthenticated access', () => {
const render = renderToString(
<Router initialEntries={['/login']}>
<RoutePublic
exact
path="/login"
component={() => <div>LOGIN</div>}
isAuthenticated={false}
/>
</Router>,
);
expect(render).toMatchSnapshot();
});
it('should redirect to /private for authenticated access', () => {
const render = renderToString(
<Router initialEntries={['/login']}>
<RoutePublic
exact
path="/login"
component={() => <div>LOGIN</div>}
isAuthenticated={true}
/>
</Router>,
);
expect(render).toMatchSnapshot();
});
});
Example #6
Source File: RoutePrivate.spec.js From full-stack-fastapi-react-postgres-boilerplate with MIT License | 6 votes |
describe('RoutePrivate', () => {
it('should redirect for unauthenticated access', () => {
const render = renderToString(
<Router initialEntries={['/private']}>
<RoutePrivate
exact
path="/private"
component={() => <div>PRIVATE</div>}
isAuthenticated={false}
/>
</Router>,
);
expect(render).toMatchSnapshot();
});
it('should allow navigation for authenticated access', () => {
const render = renderToString(
<Router initialEntries={['/private']}>
<RoutePrivate
exact
path="/private"
component={() => <div>PRIVATE</div>}
isAuthenticated={true}
/>
</Router>,
);
expect(render).toMatchSnapshot();
});
});
Example #7
Source File: server.jsx From react-enterprise-starter-kit with MIT License | 6 votes |
server.get('/', (req, res) => {
console.log('Middle Ware Called');
console.log(path.resolve('./dist/index.html'));
const data = fs.readFileSync(path.resolve('./dist/index.html'), 'utf8');
const content = renderToString(
<Provider store={store}>
<App />
</Provider>,
);
const preloadedState = `<script type="text/javascript" charset="utf-8"> window.__PRELOADED__STATE__ = ${JSON.stringify(store)} </script>`;
const serverRenderedHTML = data.replace(
'<div id="root"></div>',
`<div id="root">${content}</div>${preloadedState}`,
);
res.status(200).send(serverRenderedHTML);
// store.runSaga(rootSagas).toPromise()
// .then(() => {
// console.log('Saga Run Successfully');
// // res.status(200).send(serverRenderedHTML);
// })
// .catch((e) => {
// console.log('Saga Run Failed', e.message);
// // res.status(500).send(e.message);
// });
});
Example #8
Source File: ssr.js From ReactCookbook-source with MIT License | 6 votes |
app.use('*', async (req, res) => {
let componentData = {};
let indexHTML = fs.readFileSync(path.resolve(__dirname, '../build/index.html'), {
encoding: 'utf8',
});
let appHTML = renderToString(
<StaticRouter location={req.originalUrl} context={componentData}>
<App/>
</StaticRouter>
);
indexHTML = indexHTML.replace('<div id="root"></div>', `<div id="app">${appHTML}</div>`);
indexHTML = indexHTML.replace(
'var initial_state = null;',
`var initial_state = ${JSON.stringify(componentData)};`
);
// set header and status
res.contentType('text/html');
res.status(200);
return res.send(indexHTML);
});
Example #9
Source File: ssr-handler.js From divar-starter-kit with MIT License | 6 votes |
function getPageMarkup({
store, context, preloadedData, location,
}) {
const { Provider: InitialSSRDataProvider } = createNewContext();
return renderToString(
<Provider store={store}>
<InitialSSRDataProvider value={initSSRContextValue(preloadedData)}>
<StaticRouter context={context} location={location}>
<AppRouter />
</StaticRouter>
</InitialSSRDataProvider>
</Provider>,
);
}
Example #10
Source File: index.js From citr-v6-project with Apache License 2.0 | 6 votes |
app.use((req, res) => {
const staticContext = {};
const reactMarkup = (
<StaticRouter url={req.url} context={staticContext}>
<App />
</StaticRouter>
);
res.status(staticContext.statusCode || 200);
res.send(`${parts[0]}${renderToString(reactMarkup)}${parts[1]}`);
res.end();
});
Example #11
Source File: SSR.test.js From react-menu with MIT License | 6 votes |
describe('Server rendering', () => {
test('portal is not provided', () => {
expect(renderToString(getMenu())).toContain(
'</button><div class="szh-menu-container" style="position:relative"><ul role="menu"'
);
});
test('portal is true', () => {
expect(renderToString(getMenu({ portal: true }))).toContain(
'</button><div class="szh-menu-container" style="position:relative"><ul role="menu"'
);
});
test('portal.target is null', () => {
expect(renderToString(getMenu({ portal: { target: null } }))).toContain(
'</button><div class="szh-menu-container" style="position:relative"><ul role="menu"'
);
});
test('portal.stablePosition is true', () => {
expect(renderToString(getMenu({ portal: { stablePosition: true } }))).toContain(
'</button></main>'
);
});
});
Example #12
Source File: server.js From Learning-Redux with MIT License | 6 votes |
handleRender = (req, res) => {
// Query our mock API asynchronously
fetchCounter((apiResult) => {
// Read the counter from the request, if provided
const params = qs.parse(req.query)
const counter = parseInt(params.counter, 10) || apiResult || 0
// Compile an initial state
const preloadedState = { counter }
// Create a new Redux store instance
const store = configureStore(preloadedState)
// Render the component to a string
const html = renderToString(
<Provider store={store}>
<App />
</Provider>
)
// Grab the initial state from our Redux store
const finalState = store.getState()
// Send the rendered page back to the client
res.send(renderFullPage(html, finalState))
})
}
Example #13
Source File: entry.server.jsx From redis-examples with MIT License | 6 votes |
export default function handleRequest(
request,
responseStatusCode,
responseHeaders,
remixContext
) {
const markup = renderToString(
<RemixServer context={remixContext} url={request.url} />
);
responseHeaders.set("Content-Type", "text/html");
return new Response("<!DOCTYPE html>" + markup, {
status: responseStatusCode,
headers: responseHeaders,
});
}
Example #14
Source File: server.js From Learning-Redux with MIT License | 6 votes |
handleRender = (req, res) => {
// Query our mock API asynchronously
fetchCounter((apiResult) => {
// Read the counter from the request, if provided
const params = qs.parse(req.query);
const counter = parseInt(params.counter, 10) || apiResult || 0;
// Compile an initial state
const preloadedState = { counter };
// Create a new Redux store instance
const store = configureStore(preloadedState);
// Render the component to a string
const html = renderToString(
<Provider store={store}>
<App />
</Provider>
);
// Grab the initial state from our Redux store
const finalState = store.getState();
// Send the rendered page back to the client
res.send(renderFullPage(html, finalState));
});
}
Example #15
Source File: entry-server.jsx From reactplate with MIT License | 5 votes |
export function render(url, context) {
return renderToString(
<StaticRouter location={url} context={context}>
<App />
</StaticRouter>
);
}
Example #16
Source File: test.js From react-instagram-zoom-slider with MIT License | 5 votes |
describe('Server-side rendering', () => {
it('renders on a server without crashing', () => {
const slides = [<img src="..." alt="First slide" />, <img src="..." alt="Second slide" />]
const renderOnServer = () => renderToString(<Slider initialSlide={1} slides={slides} />)
expect(renderOnServer).not.toThrow()
})
})
Example #17
Source File: server.js From react-keycloak-examples with MIT License | 5 votes |
server
.disable('x-powered-by')
.use(express.static(process.env.RAZZLE_PUBLIC_DIR))
.use(cookieParser()) // 1. Add cookieParser Express middleware
.get('/*', (req, res) => {
const context = {}
// 2. Create an instance of ServerPersistors.ExpressCookies passing the current request
const cookiePersistor = ServerPersistors.ExpressCookies(req)
// 3. Wrap the App inside SSRKeycloakProvider
const markup = renderToString(
<SSRKeycloakProvider
keycloakConfig={getKeycloakConfig()}
persistor={cookiePersistor}
>
<StaticRouter context={context} location={req.url}>
<App />
</StaticRouter>
</SSRKeycloakProvider>
)
if (context.url) {
res.redirect(context.url)
} else {
res.status(200).send(
`<!doctype html>
<html lang="">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta charset="utf-8" />
<title>Welcome to Razzle</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script>window.env = ${JSON.stringify(getKeycloakConfig())}</script>
${
assets.client.css
? `<link rel="stylesheet" href="${assets.client.css}">`
: ''
}
${
process.env.NODE_ENV === 'production'
? `<script src="${assets.client.js}" defer></script>`
: `<script src="${assets.client.js}" defer crossorigin></script>`
}
</head>
<body>
<div id="root">${markup}</div>
</body>
</html>`
)
}
})
Example #18
Source File: server.js From module-federation-examples with MIT License | 5 votes |
app.get('*', (req, res, next) => {
const html = renderToString(<App />);
res.send(html);
});
Example #19
Source File: render.js From tunnel-tool with MIT License | 5 votes |
render = (
{
App,
paths: { resources: RESOURCES_BASE_ROUTE, base: BASE_ROUTE },
urls: {
external: { graphql: EXTERNAL_URL_GRAPH, events: EXTERNAL_URL_EVENTS },
internal: { graphql: INTERNAL_URL_GRAPH, events: INTERNAL_URL_EVENTS }
},
watchers,
reducers,
req,
res
},
cxt
) => {
let routerContext = {};
const { store } = configureStore({ reducers, initState: {} });
const { graph } = configureGraph({
url: INTERNAL_URL_GRAPH,
req,
initState: {}
});
const AppRoot = (
<ApolloProvider client={graph}>
<Provider store={store}>
<StaticRouter location={req.url} context={routerContext}>
<App />
</StaticRouter>
</Provider>
</ApolloProvider>
);
getDataFromTree(AppRoot)
.then(() => {
const preloadedState = store.getState();
const htmlSteam =
Template.header({
paths: { base: BASE_ROUTE, resources: RESOURCES_BASE_ROUTE }
}) +
renderToString(AppRoot) +
Template.footer({
config: {
paths: { base: BASE_ROUTE, resources: RESOURCES_BASE_ROUTE },
urls: {
graphql: EXTERNAL_URL_GRAPH,
events: EXTERNAL_URL_EVENTS
}
},
preloadedState,
preloadedGraphState: graph.extract()
});
if (routerContext.url) {
res.redirect(routerContext.url);
} else {
res.status(200);
res.send(htmlSteam);
}
})
.catch(function(error) {
console.log(error);
});
}
Example #20
Source File: server.js From react-workshop with MIT License | 5 votes |
server
.disable('x-powered-by')
.use(express.static(process.env.RAZZLE_PUBLIC_DIR))
.get('/*', (req, res) => {
const apolloClient = new ApolloClient({
ssrMode: true,
cache: new InMemoryCache(),
link: createHttpLink({
uri: 'https://asia-southeast2-minitokopedia.cloudfunctions.net/graphql',
}),
});
const context = {};
const markup = (
<ApolloProvider client={apolloClient}>
<StaticRouter context={context} location={req.url}>
<App />
</StaticRouter>
</ApolloProvider>
);
if (context.url) {
res.redirect(context.url);
} else {
getDataFromTree(markup).then((content) => {
const initialState = apolloClient.extract();
const html = renderToString(
<html lang="en">
<head>
<meta httpEquiv="X-UA-Compatible" content="IE=edge" />
<meta charset="utf-8" />
<title>Welcome to Razzle</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
{cssLinksFromAssets(razzleAssets, 'client')}
</head>
<body>
<div id="root" dangerouslySetInnerHTML={{ __html: content }} />
<script
dangerouslySetInnerHTML={{
__html: `window.__APOLLO_STATE__=${JSON.stringify(initialState).replace(/</g, '\\u003c')};`,
}}
/>
{jsScriptTagsFromAssets(razzleAssets, 'client')}
</body>
</html>,
);
res.status(200).header('Content-Type', 'text/html').send(`<!doctype html>\n${html}`);
});
}
});
Example #21
Source File: render.js From ReactSourceCodeAnalyze with MIT License | 5 votes |
export default function render() {
var html = renderToString(<App assets={assets} />);
// There's no way to render a doctype in React so prepend manually.
// Also append a bootstrap script tag.
return '<!DOCTYPE html>' + html;
}
Example #22
Source File: MapView.jsx From resilience-app with GNU General Public License v3.0 | 5 votes |
function MissionMarker({ currentUid, groups, mission, setSelectedMission, volunteers }) {
const classes = useStyles();
const [anchorEl, setAnchorEl] = React.useState(null);
let html = `<div class='${clsx(
classes.markerPin,
currentUid === mission.uid && classes.currentMarker
)}'></div>`;
let color = "black";
if (mission.groupDisplayName) {
color = _.randomColor(mission.groupDisplayName);
const GroupIconHtml = renderToString(
<GroupWorkIcon className={classes.customGroupIcon} style={{ color: color }} />
);
html += GroupIconHtml;
}
const FoodboxIconHtml = renderToString(<FoodBoxIcon className={classes.innerFoodBoxMarker} />);
html += FoodboxIconHtml;
const CustomIcon = new DivIcon({
className: clsx(classes.customDivIcon),
html: html,
iconSize: [30, 42],
iconAnchor: [15, 42], // half of width + height
});
return (
<Marker
icon={CustomIcon}
key={mission.uid}
position={mission.deliveryLocation}
onClick={(event) => {
setAnchorEl(event.target.getElement());
setSelectedMission(mission.uid);
}}
>
<Popup className={classes.popup} autoClose={true}>
<Grid container>
<Grid container item xs>
{mission.groupDisplayName}
{mission.details?.map((box, index) => {
return (
<div key={index}>
{box.quantity} x {box.displayName}
</div>
);
})}
</Grid>
<Grid item>
<MissionItemMenu
groups={groups}
mission={mission}
volunteers={volunteers}
boxRef={{ current: anchorEl }}
/>
</Grid>
</Grid>
</Popup>
</Marker>
);
}
Example #23
Source File: render.js From Learning-Redux with MIT License | 5 votes |
serverSideRendering = (indexFile, loadStaticFile) => (req, res) => {
const isIndexPage = req.url === "/" || req.url === "/index.html";
if (isIndexPage) {
if (cachedResult) return res.send(cachedResult);
}
console.log("server-side rendering started for", req.url);
const history = createHistory();
const store = configureStore({}, history, true);
return initStore(store)
.then(() => {
const context = {};
const markup = renderToString(
<Provider store={store}>
<StaticRouter
location={isIndexPage ? "/" : req.url}
context={context}
>
<App />
</StaticRouter>
</Provider>
);
const storeState = JSON.stringify(store.getState()).replace(
/</g,
"\\u003c"
);
const dom = new JSDOM(indexFile, { runScripts: "outside-only" });
dom.window.eval(`
document.getElementById('root').innerHTML = '${markup}'
`);
dom.window.eval(`
var script = document.createElement('script')
script.innerHTML = 'window.__PRELOADED_STATE__ = ${storeState}'
document.body.insertBefore(script,
document.getElementsByTagName('script')[0]
)
`);
if (isIndexPage) {
cachedResult = dom.serialize();
console.log("server-side rendering done, cached result");
if (res) return res.send(cachedResult);
} else {
console.log("server-side rendering done");
if (res) return res.send(dom.serialize());
}
})
.catch((err) => {
console.error("server-side rendering error:", err);
if (loadStaticFile) return loadStaticFile(req, res);
});
}
Example #24
Source File: server.js From Edlib with GNU General Public License v3.0 | 4 votes |
renderApp = async (req, res) => {
const context = {};
const emotionCache = createEmotionCache();
const sheet = new ServerStyleSheet();
const emotionServers = [
// Every emotion cache used in the app should be provided.
// Caches for MUI should use "prepend": true.
// MUI cache should come first.
emotionCache,
getTssDefaultEmotionCache({ doReset: true }),
].map(createEmotionServer);
const wwwUrl = `${req.protocol}://${req.get('host')}`;
const SetupApp = (initialState, promiseList = []) => (
<CacheProvider value={emotionCache}>
<ThemeProvider theme={muiTheme}>
<StaticRouter context={context} location={req.url}>
<FetchProvider
promiseList={promiseList}
initialState={initialState}
ssrCookies={res.getCookies()}
ssrAddCookiesFromSetCookie={res.addCookiesFromSetCookie}
>
<ConfigurationProvider
apiUrl={wwwUrl.replace('www', 'api')}
wwwUrl={wwwUrl}
isSSR
cookies={req.cookies}
>
<App />
</ConfigurationProvider>
</FetchProvider>
</StaticRouter>
</ThemeProvider>
</CacheProvider>
);
const maxDepth = 10;
const getStateFromTree = async (state = {}, depth = 0) => {
const promiseList = [];
renderToString(SetupApp(state, promiseList));
if (promiseList.length !== 0 && depth < maxDepth) {
await addPromiseListToState(state, promiseList);
return getStateFromTree(state, depth + 1);
}
return { state };
};
const { state } = await getStateFromTree();
const markup = renderToString(sheet.collectStyles(SetupApp(state, [])));
const helmet = Helmet.renderStatic();
// Grab the CSS from emotion
const styleTagsAsStr = emotionServers
.map(({ extractCriticalToChunks, constructStyleTagsFromChunks }) =>
constructStyleTagsFromChunks(extractCriticalToChunks(markup))
)
.join('');
// Grab the CSS from styled-components
const styledComponentsTags = sheet.getStyleTags();
const html = `<!doctype html>
<html lang="">
<head ${helmet.htmlAttributes.toString()}>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
${cssLinksFromAssets(assets, 'client')}
${styleTagsAsStr}
${styledComponentsTags}
${helmet.title.toString()}
${helmet.meta.toString()}
${helmet.link.toString()}
</head>
<body ${helmet.bodyAttributes.toString()}>
<script>
window.__FETCH_STATE__=${JSON.stringify(state).replace(
/</g,
'\\u003c'
)};
</script>
<div id="root">${markup}</div>
${jsScriptTagsFromAssets(assets, 'client', 'defer', 'crossorigin')}
</body>
</html>`;
return { context, html };
}
Example #25
Source File: server-rendering.spec.js From Learning-Redux with MIT License | 4 votes |
describe('React', () => {
describe('server rendering', () => {
function greetingReducer(state = { greeting: 'Hello' }, action) {
return action && action.payload ? action.payload : state
}
const Greeting = ({ greeting, greeted }) => greeting + ' ' + greeted
const ConnectedGreeting = connect((state) => state)(Greeting)
const Greeter = (props) => (
<div>
<ConnectedGreeting {...props} />
</div>
)
class Dispatcher extends React.Component {
constructor(props) {
super(props)
if (props.constructAction) {
props.dispatch(props.constructAction)
}
}
UNSAFE_componentWillMount() {
if (this.props.willMountAction) {
this.props.dispatch(this.props.willMountAction)
}
}
render() {
if (this.props.renderAction) {
this.props.dispatch(this.props.renderAction)
}
return <Greeter greeted={this.props.greeted} />
}
}
const ConnectedDispatcher = connect()(Dispatcher)
it('should be able to render connected component with props and state from store', () => {
const store = createStore(greetingReducer)
const markup = renderToString(
<Provider store={store}>
<Greeter greeted="world" />
</Provider>
)
expect(markup).toContain('Hello world')
})
it('should run in an SSR environment without logging warnings about useLayoutEffect', () => {
const store = createStore(greetingReducer)
const spy = jest.spyOn(console, 'error').mockImplementation(() => {})
const markup = renderToString(
<Provider store={store}>
<Greeter greeted="world" />
</Provider>
)
expect(spy).toHaveBeenCalledTimes(0)
spy.mockRestore()
})
it('should render with updated state if actions are dispatched before render', () => {
const store = createStore(greetingReducer)
store.dispatch({ type: 'Update', payload: { greeting: 'Hi' } })
const markup = renderToString(
<Provider store={store}>
<Greeter greeted="world" />
</Provider>
)
expect(markup).toContain('Hi world')
expect(store.getState().greeting).toContain('Hi')
})
it('should render children with updated state if actions are dispatched in ancestor', () => {
/*
Dispatching during construct, render or willMount is
almost always a bug with SSR (or otherwise)
This behaviour is undocumented and is likely to change between
implementations, this test only verifies current behaviour
Note: this test fails in v6, because we use context to propagate the store state, and the entire
tree will see the same state during the render pass.
In all other versions, including v7, the store state may change as actions are dispatched
during lifecycle methods, and components will see that new state immediately as they read it.
*/
const store = createStore(greetingReducer)
const constructAction = { type: 'Update', payload: { greeting: 'Hi' } }
const willMountAction = { type: 'Update', payload: { greeting: 'Hiya' } }
const renderAction = { type: 'Update', payload: { greeting: 'Hey' } }
const markup = renderToString(
<Provider store={store}>
<ConnectedDispatcher
constructAction={constructAction}
greeted="world"
/>
<ConnectedDispatcher
willMountAction={willMountAction}
greeted="world"
/>
<ConnectedDispatcher renderAction={renderAction} greeted="world" />
</Provider>
)
expect(markup).toContain('Hi world')
expect(markup).toContain('Hiya world')
expect(markup).toContain('Hey world')
expect(store.getState().greeting).toContain('Hey')
})
it('should render children with changed state if actions are dispatched in ancestor and new Provider wraps children', () => {
/*
Dispatching during construct, render or willMount is
almost always a bug with SSR (or otherwise)
This behaviour is undocumented and is likely to change between
implementations, this test only verifies current behaviour
This test works both when state is fetched directly in connected
components and when it is fetched in a Provider and placed on context
*/
const store = createStore(greetingReducer)
const constructAction = { type: 'Update', payload: { greeting: 'Hi' } }
const willMountAction = { type: 'Update', payload: { greeting: 'Hiya' } }
const renderAction = { type: 'Update', payload: { greeting: 'Hey' } }
const markup = renderToString(
<Provider store={store}>
<ConnectedDispatcher
constructAction={constructAction}
greeted="world"
/>
<ConnectedDispatcher
willMountAction={willMountAction}
greeted="world"
/>
<ConnectedDispatcher renderAction={renderAction} greeted="world" />
</Provider>
)
expect(markup).toContain('Hi world')
expect(markup).toContain('Hiya world')
expect(markup).toContain('Hey world')
expect(store.getState().greeting).toContain('Hey')
})
})
})
Example #26
Source File: server.js From littlelink-server with MIT License | 4 votes |
server
.disable('x-powered-by')
.use(express.static(process.env.RAZZLE_PUBLIC_DIR))
.get('/', (req, res) => {
const context = {};
const markup = renderToString(
<StaticRouter context={context} location={req.url}>
<App />
</StaticRouter>,
);
if (context.url) {
res.redirect(context.url);
} else {
res.status(200).send(
`<!doctype html>
<html lang="${runtimeConfig.LANG || 'en'}">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta charset="utf-8" />
<title >${runtimeConfig.META_TITLE}</title>
<meta name="description" content="${runtimeConfig.META_DESCRIPTION}">
<meta name="author" content="${runtimeConfig.META_AUTHOR}">
<meta name="keywords" content="${runtimeConfig.META_KEYWORDS}">
<meta name="robots" content="${
runtimeConfig.META_INDEX_STATUS || 'noindex'
}">
<meta name="viewport" content="width=device-width, initial-scale=1">
${
runtimeConfig.OG_SITE_NAME
? `<meta property="og:site_name" content="${runtimeConfig.OG_SITE_NAME}" />`
: ''
}
${
runtimeConfig.OG_TITLE
? `<meta property="og:title" content="${runtimeConfig.OG_TITLE}" />`
: ''
}
${
runtimeConfig.OG_DESCRIPTION
? `<meta property="og:description" content="${runtimeConfig.OG_DESCRIPTION}" />`
: ''
}
${
runtimeConfig.OG_URL
? `<meta property="og:url" content="${runtimeConfig.OG_URL}" />`
: ''
}
<meta property="og:type" content="siteweb" />
${
runtimeConfig.OG_IMAGE
? `
<meta property="og:image" content="${runtimeConfig.OG_IMAGE}" />
<meta property="og:image:secure_url" content="${runtimeConfig.OG_IMAGE}" />
`
: ''
}
${
runtimeConfig.OG_IMAGE_WIDTH
? `<meta property="og:image:width" content="${runtimeConfig.OG_IMAGE_WIDTH}" />`
: ''
}
${
runtimeConfig.OG_IMAGE_HEIGHT
? `<meta property="og:image:height" content="${runtimeConfig.OG_IMAGE_HEIGHT}" />`
: ''
}
${
runtimeConfig.TWITTER_CARD
? `<meta property="twitter:card" content="${runtimeConfig.TWITTER_CARD}" />`
: ''
}
${
runtimeConfig.TWITTER_IMAGE
? `<meta property="twitter:image" content="${runtimeConfig.TWITTER_IMAGE}" />`
: ''
}
${
runtimeConfig.TWITTER_SITE
? `<meta property="twitter:site" content="${runtimeConfig.TWITTER_SITE}" />`
: ''
}
${
runtimeConfig.TWITTER_CREATOR
? `<meta property="twitter:creator" content="${runtimeConfig.TWITTER_CREATOR}" />`
: ''
}
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,600,700,800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/${theme}">
<link rel="stylesheet" href="css/brands.css">
${cssLinksFromAssets(assets, 'client')}
<link rel="icon" type="image/png" href="${runtimeConfig.FAVICON_URL}">
${
runtimeConfig.GA_TRACKING_ID
? `
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=${runtimeConfig.GA_TRACKING_ID}"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${runtimeConfig.GA_TRACKING_ID}');
</script>`
: ''
}
${
runtimeConfig.UMAMI_WEBSITE_ID && runtimeConfig.UMAMI_APP_URL
? `
<!-- Umami Analytics -->
<script async defer data-website-id="${runtimeConfig.UMAMI_WEBSITE_ID}" src="${runtimeConfig.UMAMI_APP_URL}/umami.js">
</script>`
: ''
}
${
runtimeConfig.MATOMO_URL && runtimeConfig.MATOMO_SITE_ID
? `
<!-- Matomo -->
<script type="text/javascript">
var _paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function () {
var u = "${runtimeConfig.MATOMO_URL}/";
_paq.push(['setTrackerUrl', u + 'matomo.php']);
_paq.push(['setSiteId', '${runtimeConfig.MATOMO_SITE_ID}']);
var d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0];
g.type = 'text/javascript';
g.async = true;
g.defer = true;
g.src = u + 'matomo.js';
s.parentNode.insertBefore(g, s);
})();
</script>
<!-- Matomo End -->`
: ''
}
</head>
<body>
${
runtimeConfig.MATOMO_URL && runtimeConfig.MATOMO_SITE_ID
? `
<!-- Matomo Image Tracker-->
<img referrerpolicy="no-referrer-when-downgrade" src="${runtimeConfig.MATOMO_URL}/matomo.php?idsite=${runtimeConfig.MATOMO_SITE_ID}&rec=1" style="border:0" alt="" />
<!-- End Matomo -->`
: ''
}
<div id="root">${markup}</div>
<script>window.env = ${serialize(runtimeConfig)};</script>
${jsScriptTagsFromAssets(assets, 'client', ' defer crossorigin')}
</body>
</html>`,
);
}
});
Example #27
Source File: load-routes.js From crate with MIT License | 4 votes |
export default function (app) {
console.info('SETUP - Load routes..')
// Store (new store for each request)
const store = createStore(
rootReducer,
applyMiddleware(thunk)
)
// Match any Route
app.get('*', (request, response) => {
// Check for auth
if (request.cookies.auth) {
const auth = JSON.parse(request.cookies.auth)
if (auth && auth.token !== '' && auth.user) {
store.dispatch(setUser(auth.token, auth.user))
}
}
// HTTP status code
let status = 200
const matches = Object.values(routes).reduce((matches, route) => {
const match = matchPath(request.url, typeof route.path === 'function' ? route.path() : route.path, route)
if (match && match.isExact) {
matches.push({
route,
match,
promise: route.component.fetchData ? route.component.fetchData({
store,
params: match.params
}) : Promise.resolve(null)
})
}
return matches
}, [])
// No such route, send 404 status
if (matches.length === 0) {
status = 404
}
// Any AJAX calls inside components
const promises = matches.map((match) => {
return match.promise
})
// Resolve the AJAX calls and render
Promise.all(promises)
.then((...data) => {
const initialState = store.getState()
const context = {}
const appHtml = renderToString(
<Provider store={store} key="provider">
<StaticRouter context={context} location={request.url}>
<App/>
</StaticRouter>
</Provider>
)
if (context.url) {
response.redirect(context.url)
} else {
// Get Meta header tags
const helmet = Helmet.renderStatic()
const styles = flushToHTML()
const html = view(APP_URL, NODE_ENV, helmet, appHtml, styles, initialState)
// Reset the state on server
store.dispatch({
type: 'RESET'
})
// Finally send generated HTML with initial data to the client
return response.status(status).send(html)
}
})
.catch(error => {
console.error(error)
})
})
}