o2web-react-core
v0.9.3
Published
O2 Web React Core
Downloads
12
Keywords
Readme
o2web-react-core
Install
npm install --save o2web-react-core
Usage
Available components and methods
// using ES6 modules
import {
BaseRoute,
CacheBuster,
CrumbRoute,
LanguageSwitcher,
GAListener,
NavLink,
Redirector,
Route,
translateRoute,
ValidateRoutes,
} from 'o2web-react-core';
Example in /example
GraphQL Requests
This package uses Apollo Client as GraphQL client.
Duplicate .env.sample
file and add GraphQL endpoint
REACT_APP_API_URL=https://example.com/graphql
Check /example/src/app/actions/artworks
directory for GraphQL queries definition examples
export default {
fetchArtwork: `
query($id: ID!) {
artwork(id: $id) {
id
name
description
}
}
`,
fetchArtworks: `
query($limit: Int) {
artworks(limit: $limit) {
artworks {
id
name
description
}
}
}
`,
};
Authentication
This package is intended to authenticate with a GraphQL Authentication with JWT. You can use the gem graphql-auth if you are using rails for your api
The authentication forms Components are located in `example/src/app/components/user
Redux
This package uses Redux to manage data states
Check /example/src/app/reducers
directory for reducers stucture
import { combineReducers } from 'redux';
import { i18nState } from 'redux-i18n';
import { reducer as formReducer } from 'redux-form';
import artworkReducer from './artwork';
import artworksReducer from './artworks';
const rootReducer = combineReducers({
i18nState,
form: formReducer,
artwork: artworkReducer,
artworks: artworksReducer,
});
export default rootReducer;
react-redux is use to connect Redux data state to React components
import { connect } from 'react-redux';
...
export default connect(mapStateToProps, actions)(Artworks);
This package also uses redux-action-creator to define Redux actions types
Check /example/src/app/actions/artworks
directory for redux action types examples
import { async, createTypes } from 'redux-action-creator';
export default createTypes([
...async('FETCH_ARTWORK'),
...async('FETCH_ARTWORKS'),
], 'ARTWORKS');
Define the Redux Store this way src/config/redux/store.js
import reduxThunk from 'redux-thunk';
import { createStore, applyMiddleware } from 'redux';
import reducers from '../../app/reducers/index';
const middlewares = [reduxThunk];
const createStoreWithMiddleware = applyMiddleware(...middlewares)(createStore);
const store = createStoreWithMiddleware(reducers);
export default store;
Translations
This package uses redux-i18n for texts translation
Check /example/src/app/components/pages/About.js
for translation examples
function About(pros, { t }) {
return (
<div>
<h2>{t('pages.titles.about')}</h2>
</div>
);
}
About.contextTypes = {
t: PropTypes.func,
};
Create a directory with translations in /example/src/config/locales
directory
t('pages.titles.about')
matches /example/src/config/locales/en/pages.js
definition
export default {
titles: {
home: 'Home page',
about: 'About page',
},
};
Translation keys can be nested
Router
This package uses react-router v4 to define translated routes. These routes must be named with their translations keys.
Check /example/src/config/locales/en/routes.js
for routes definitions
export default {
en: 'en',
about: 'about',
artworks: 'artworks',
demo: 'demo-form',
};
<BaseRoute />
, <LanguageSwitcher />
, <NavLink />
, <Route />
can be used for translated routes
Breadcrumbs
This package uses react-breadcrumbs to generate automatic breadcrumbs.
Routes must be nested so react-breadcrumbs can generate breadcrumbs.
Check /example/src/app/components/layouts/PrimaryLayout.js
for automatic breadcrumbs definition examples
<main>
<Breadcrumbs />
<Route exact path="/en" component={HomePage} />
<CrumbRoute exact path="/en/about" title="about" component={AboutPage} />
<CrumbRoute
path="/en/artworks"
title="artworks"
render={({ match }) =>
<Switch>
<Route exact path={match.url} component={Artworks} />
<CrumbRoute path={`${match.url}/:artworkId`} title="artwork" component={Artwork} />
</Switch>
}
/>
<CrumbRoute exact path="/en/demo" title="demo" component={DemoForm} />
</main>
<CrumbRoute />
can be used for translated routes
Redirects
Update redirects array located at /example/src/config/redirects/redirects.js
const redirects = [
{ from: '/en/route', to: '/en/redirect-to' },
];
SEO
This package uses react-helmet to manage document head
<Helmet />
can be used in nested components. The most nested definition will be displayed in the page.
Check /example/src/app/components/App.js
for document head definition example
Tag Manager
Add GTM ID in the .env file REACT_APP_TAG_MANAGER_ID=GTM-000000
.
Use https://www.npmjs.com/package/react-gtm-module
.
Forms
This packages uses redux-form for form definition
Check /example/src/app/components/forms/Demo.js
for form example
import { Field, reduxForm } from 'redux-form';
import Input from './fields/input/Input';
<form onSubmit={submitForm} className="form--demo">
<Field
name="firstName"
component={Input}
type="text"
placeholder="Your name..."
/>
...
export default connect(mapStateToProps)(reduxForm({
form: 'demo',
enableReinitialize: true,
validate,
}, mapStateToProps)(DemoForm));
Cookies
This package uses redux-cookie
<CookiesProvider />
is defined in /example/src/app/components/App.js
so cookies
prop is available to children components
CacheBuster
This article was used to create the CacheBuster component.
React apps can sometimes get stuck on the client's side cache (ex: when the app is added to the phone's homepage). You can use the CacheBuster component to help refresh the app. Here are the steps to help you set it up.
- Copy the
generate-build-version.js
script to your app folder - Add the
generate-build-version
task to your app'spackage.json
and call it with the prestart/prebuild hook. This will generate a meta.json file in yourstatic
folder.
"scripts": {
"generate-build-version": "node ./generate-build-version.js",
"prestart": "npm run generate-build-version",
"pressr:build": "npm run generate-build-version",
"prestatic:build": "npm run generate-build-version"
[...]
"static:build": "REACT_APP_CURRENT_APP_VERSION=$npm_package_version react-app-rewired build", # hosted on Heroku
"static:build": "react-app-rewired build", # not hosted on Heroku
[...]
},
- If your app is hosted on Heroku, you must add this
REACT_APP_CURRENT_APP_VERSION=$npm_package_version
to the build and start script in package.json to include the current version in your build. - If your app is not hosted on Heroku, you can simply add
REACT_APP_CURRENT_APP_VERSION=$npm_package_version
to your .env file. - In the root component of your App (generally
src/app/components/App.js
), add the CacheBuster component around your app code - The CacheBuster will now compare the current version, from your
.env
file, which should be cached, and the current build version, from thegenerate-build-version.js
, which should not be cached, because we fetch it asynchronously and browsers don't cache XHR requests.
Advanced usage
Add custom Apollo client
You can add a custom Apollo client to further customize your app with advanced features. To do so, you need to create a custom client, import it in your action files and send it as a parameter to the async query object. You can find an example of this feature in the example folder (custom client in example/src/config/graphql/client.js
and usage in example/src/app/actions/artworks/index.js
).
Development
Start package core
cd /
npm install
npm start
Start example app
cd /example
npm install
npm start
Run server build
To run the server build update package.json
at the root of the project to point to the server build.
"ssr:serve": "nodemon -r dotenv/config ./example/build/server.js",
Javascript Linting
This package uses ESLint with Airbnb React/JSX Style Guide as React/JSX style guide
Package created with create-react-library
License
MIT © o2web