README.md in quilt_rails-1.11.1 vs README.md in quilt_rails-1.12.0

- old
+ new

@@ -9,20 +9,22 @@ - [Generate Rails boilerplate](#generate-rails-boilerplate) - [Add Ruby dependencies](#add-ruby-dependencies) - [Generate Quilt boilerplate](#generate-quilt-boilerplate) - [Try it out](#try-it-out) - [Manual Install](#manual-installation) + - [Generate Rails boilerplate](#generate-rails-boilerplate) - [Install Dependencies](#install-dependencies) - [Setup the Rails app](#setup-the-rails-app) - [Add JavaScript](#add-javascript) - [Run the server](#run-the-server) - [Application Layout](#application-layout) - [Advanced Use](#advanced-use) - [Testing](#testing) - [Interacting with the request and response in React code](#interacting-with-the-request-and-response-in-react-code) - [Dealing with isomorphic state](#dealing-with-isomorphic-state) - [Customizing the node server](#customizing-the-node-server) + - [Fixing rejected CSRF tokens for new user sessions](#fixing-rejected-csrf-tokens-for-new-user-sessions) - [Performance tracking a React app](#performance-tracking-a-react-app) - [Install dependencies](#install-dependencies) - [Setup an endpoint for performance reports](setup-an-endpoint-for-performance-reports) - [Add annotations](#add-annotations) - [Send the report](#send-the-report) @@ -78,18 +80,23 @@ This will install the Node dependencies, provide a basic React app (in TypeScript) and mounts the Quilt engine inside of `config/routes.rb`. #### Try it out -`dev server` +```sh +dev up +dev server +``` Will run the application, starting up both servers and compiling assets. ### Manual installation An application can also be setup manually using the following steps. +[Generate Rails boilerplate](#generate-rails-boilerplate) + #### Install dependencies ```sh # Add ruby dependencies bundle add sewing_kit quilt_rails @@ -98,10 +105,29 @@ yarn add @shopify/sewing-kit @shopify/react-server # Add React yarn add react react-dom +# Add Typescript +yarn add typescript @types/react @types/react-dom +``` + +##### Define typescript config + +```json +// tsconfig.json +{ + "extends": "@shopify/typescript-configs/application.json", + "compilerOptions": { + "baseUrl": ".", + "rootDir": "." + }, + "include": ["app/ui"] +} +``` + +```sh yarn dev up ``` #### Setup the Rails app @@ -301,71 +327,49 @@ } export default App; ``` -##### Example: sending headers from Rails controller +##### Example: sending custom data from Rails controller +In some cases you may want to send custom headers or basic data from Rails to your React server. Quilt facilitates this case by providing consumers with a `headers` and `data` argument on the `render_react` call. + +**Note:** The data passed should be data that is unlikely or will never change over the course of the session before they render any React components. + ```ruby class ReactController < ApplicationController include Quilt::ReactRenderable def index - render_react(headers: { 'x-custom-header': 'header-value-a' }) + render_react(headers: {'x-custom-header': 'header-value-a'}, data: {'some_id': 123}) end end ``` -You will need to serialize the result of the useRequestHeader hook in order for it to persist to the client +The React server will serialize the provided quilt data using `x-quilt-data` as the ID. You can then get this serialized data on the client with `getSerialized` from `@shopify/react-html`. ```tsx -// app/ui/foundation/CustomUniversalProvider.tsx -import {createContext} from 'react'; -import {createUniversalProvider} from '@shopify/react-universal-provider'; - -export const CustomContext = createContext<string | null>(null); -export const CustomUniversalProvider = createUniversalProvider('custom-key', CustomContext); -``` - -```tsx // app/ui/index.tsx import React from 'react'; -import {useRequestHeader} from '@shopify/react-network'; -import {CustomUniversalProvider} from './foundation/CustomUniversalProvider'; -import {ComponentWithCustomHeader} from './components/ComponentWithCustomHeader'; +import {getSerialized} from '@shopify/react-html'; +const IS_CLIENT = typeof window !== 'undefined'; + function App() { - // get `x-custom-header` from the request that was sent through Rails ReactController - const customHeader = useRequestHeader('x-custom-header'); + // get `x-quilt-data` from the request that was sent through Rails ReactController + const quiltData = IS_CLIENT ? getSerialized<{[key: string]: any}>('x-quilt-data') : null; - return ( - <CustomUniversalProvider value={customHeader}> - <h1>My application ❤️</h1> - <ComponentWithCustomHeader /> - </CustomUniversalProvider> - ); + // Logs {"x-custom-header":"header-value-a","some_id":123} + console.log(quiltData); + + return <h1>Data: {quiltData}</h1>; } export default App; ``` -```tsx -// app/ui/components/ComponentWithCustomHeader.tsx - -import React, {useContext} from 'react'; -import {CustomContext} from '../foundation/CustomUniversalProvider'; - -export function ComponentWithCustomHeader() { - // get `x-custom-header` from serialized context - // will be 'header-value-a' in this example - const customHeader = useContext(CustomContext); - - return <span>{customHeader}</span>; -} -``` - ##### Example: redirecting ```tsx // app/ui/index.tsx @@ -422,11 +426,11 @@ render(json: result) end end ``` -If your API **does** require session data, you may can use follow the following steps: +If your API **does** require session data, you can follow these steps: - Add an `x-shopify-react-xhr` header to all GraphQL requests with a value of 1 (this is done automatically if you are using `@shopify/react-graphql-universal-provider`) - Add a `protect_from_forgery with: Quilt::HeaderCsrfStrategy` override to your controllers ##### Example @@ -442,11 +446,9 @@ render(json: result) end end ``` - -- ## Performance tracking a React app Using [`Quilt::Performance::Reportable`](#performanceReportable) and [@shopify/react-performance](https://www.npmjs.com/package/@shopify/react-performance) it's easy to add performance tracking to apps using[`sewing_kit`](https://github.com/Shopify/sewing-kit/tree/master/gems/sewing_kit#sewing_kit-) for client-side-rendering or `quilt_rails` for server-side-rendering.