![require(esm) Backported to Node.js 20, Paving the Way for ESM-Only Packages](https://cdn.sanity.io/images/cgdhsj6q/production/be8ab80c8efa5907bc341c6fefe9aa20d239d890-1600x1097.png?w=400&fit=max&auto=format)
Security News
require(esm) Backported to Node.js 20, Paving the Way for ESM-Only Packages
require(esm) backported to Node.js 20, easing the transition to ESM-only packages and reducing complexity for developers as Node 18 nears end-of-life.
provide-page
Advanced tools
Provides routing, automatic server-side rendering, and automatic server-side actions to React components. Use this with `react-redux-provide` as a simpler alternative to `react-router`.
Provides routing, automatic server-side rendering, and automatic server-side actions to React components. Use this with react-redux-provide
as a simpler alternative to react-router
.
npm install provide-page --save
You can use the following actions
via propTypes
to manage the state of the document both client-side and server-side.
Uses window.history.pushState
under the hood. If this is called server-side, clients with JS disabled will be redirected to the new path.
Uses window.history.replaceState
under the hood. If this is called server-side, clients with JS disabled will be redirected to the new path.
You should typically only call the remaining
actions
below withincomponentWillMount
andcomponentWillReceiveProps
. Seetest/components/Test.js
for an example.
These optional headers will be sent to the client with SSR (server-side rendering).
An optional status code to send to the client with SSR.
Sets the document's title.
Sets the document's meta description tag.
Sets the document's meta robots tag.
Sets the document's favicon filename.
Sets the CSS filenames to be included with the document as link
elements within the head
element.
Sets the JS filenames to be included with the document as script
elements appended to the body
element.
This following action is mainly used in conjunction with the Form
component (see below), but you may trigger it manually if for some reason you need to do that.
Your components may also be provided the following reduced propTypes
.
Essentially window.location.pathname
. On the server this defaults to express
's request.originalUrl
when createMiddleware
is used (see below).
Basically windowPath.split('/')
, shifted since the first item is always empty. So for example, when your windowPath
is /foo/bar
, this will be ['foo', 'bar']
. This exists as a convenience to reduce boilerplate when rendering your routes.
The headers sent to the client when using SSR and createMiddleware
(see below).
The status code sent to the client when using SSR and createMiddleware
(see below).
The current title of the document.
The current description of the document.
How robots should treat the document. Defaults to index,follow
.
The current favicon for the document. Defaults to /static/favicon.ico
.
The current CSS files for the document.
The current JS files for the document.
Derived from request.body
when used with createMiddleware
(see below).
Derived from request.method
when used with createMiddleware
(see below).
Derived from request.headers.accept
(true
if indexOf('json') > -1
) when used with createMiddleware
(see below).
Derived from requestBody
and matching requestBody._formId
to the component's props.formId
when used with createMiddleware
and the Form
component (see below).
A simple wrapper around <a { ...props } />
, which intercepts the click event to prevent a full page reload when JavaScript is enabled and triggers the pushWindowPath
action
so the app can be updated accordingly; and of course if JS is disabled, since all your rendering logic depends on your page provider's store's state (using request.originalUrl
on the server), it all renders exactly the same as it would if JS was enabled client-side. Simply treat this as you would any other <a/>
element.
A simple wrapper around <form { ...props } />
. Combined with createMiddleware
(see below), it intercepts the onSubmit
event and allows all of your actions
to be automatically triggered on the server, whether or not JS is enabled. If JS is enabled, it will trigger the action on the server via XMLHttpRequest
. All you need is a formId
prop combined with an onSubmit
prop that accepts formData
as a second argument. The formId
prop should exist within both the Form
instance and the component instance rendering the form. See bloggur
's EntryCreator
component for a full example.
Returns a function that can be used as express
middleware and will do the following for you, server-side:
Automatically render the state of the app depending on some defaultProps
({ providers }
), the request
({ originalUrl: windowPath, method: requestMethod, body: requestBody }
), and optional formData
(see the Form
component above).
Respond with a full document string describing the current page - i.e., headers, status code, title, meta, favicon, js files, and css files - all controlled by your React components.
Automatically wait for asynchronous actions
before rendering.
When used with the Form
component (above), it will automatically trigger actions
on the server for clients with JS disabled, or if JS is enabled, the actions
will be triggered server-side via XMLHttpRequest
and the updated state of the server's stores will be returned.
Automatically redirect clients with JS disabled to a new URL when the pushWindowPath
or replaceWindowPath
actions are called.
Automatically optionally send a 408 (timeout) status when a request takes too long.
The options
object passed to createMiddleware
should take the following shape:
Extended to contain info about the request and then passed to your renderToString
function. See bloggur/src/defaultProps.js
for a full example.
This function should typically use react-dom/server
's renderToString
method under the hood to render your app to a string. See bloggur/src/renderAppToString.js
for a full example.
Optional function that returns the string representation of the entire document. The states
and clientStates
objects come form the getStates
and getClientStates
functions below. See defaultRenderDocumentToString.js
as an example.
Optional function that should return an object containing provider keys and their states, ultimately passed to both renderToString
and renderDocumentToString
. Your current providers' stores' states will be passed to this function. See bloggur/src/middleware.js
for a full example where we concatenate the selected theme's files with the cssFiles
and jsFiles
reducers so that they're included as link
and script
tags when the document string is rendered.
Optional function that should return the object to be replicated to the client. The result of getStates
is passed to this function.
Defaults to 2. After the first render, the requestMethod
and requestBody
reducers are set to GET
and an empty object, respectively. This is to ensure that actions don't get triggered twice as a result of logic depending on data submitted via some Form
and so that the app may be rendered correctly and returned within the same request. Note: If you find yourself needing to render more than twice, you may want to reconsider your design.
Default to 2000 (milliseconds). Sends a 408 status code if this timeout is reached. Setting this to 0 will disable it.
Upon initializing the store, replaceWindowPath
is automatically called which can be used to properly initialize the state of any other providers who make use of this provider's REPLACE_WINDOW_PATH
action type.
When navigating through history (i.e., when the popstate
event is triggered on the window
), if a windowPath
is present within the window.history.state
, the REPLACE_WINDOW_PATH
action type will be dispatched on top of the window.history.state
(stored action) to indicate that the window.location.pathname
has been changed; or if a documentTitle
is present for some reason, the SET_DOCUMENT_TITLE
action type will be dispatched instead.
See the following modules within bloggur
:
A combinedProvider
that depends on the current windowPath
.
Passing hot reloadable middleware to express
.
Passing production-ready, bundled middleware to express
.
Using createMiddleware
to create middleware specific to the app.
A component that renders different components based on reducers
from the entries
provider and sets the documentTitle
and statusCode
accordingly.
A component that triggers an action to create an entry on both the client and the server using the Form
component.
react-router
react-router
and others like it are all fantastic libraries, but with the providers
paradigm, there is no reason to use them. All you have to do is use provide-page
like you would any other provider and keep your routing logic within your components' render
methods. You'll find that things actually get simpler while you'll also have more control and flexibility at the same time. There's no need to try to put everything within your initial call to render
when mounting the app, as that can quickly get out of hand for large, complex applications. All you need is render(<App providers={providers} etc />)
.
The equivalent of router.transitionTo
is to provide the pushWindowPath
and/or replaceWindowPath
actions to your components and use them wherever necessary.
As for code-splitting, it should be implemented the same way themes are split. See provide-theme
for an example of how that's done. A code-splitting tutorial using provide-page
is coming soon!
FAQs
Provides automatic server-side rendering and actions (regardless of whether or not client has JavaScript enabled) to React components. Use in conjunction with `provide-router`.
We found that provide-page demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
require(esm) backported to Node.js 20, easing the transition to ESM-only packages and reducing complexity for developers as Node 18 nears end-of-life.
Security News
PyPI now supports iOS and Android wheels, making it easier for Python developers to distribute mobile packages.
Security News
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.