README.md in quilt_rails-1.10.0 vs README.md in quilt_rails-1.11.1
- old
+ new
@@ -89,10 +89,13 @@
An application can also be setup manually using the following steps.
#### Install dependencies
```sh
+# Add ruby dependencies
+bundle add sewing_kit quilt_rails
+
# Add core Node dependencies
yarn add @shopify/sewing-kit @shopify/react-server
# Add React
yarn add react react-dom
@@ -385,68 +388,65 @@
`useSerialized` can be used to implement [universal-providers](https://github.com/Shopify/quilt/tree/master/packages/react-universal-provider#what-is-a-universal-provider-), allowing application code to manage what is persisted between the server and client without adding any custom code to client or server entrypoints. We offer some for common use cases such as [CSRF](https://github.com/Shopify/quilt/tree/master/packages/react-csrf-universal-provider), [GraphQL](https://github.com/Shopify/quilt/tree/master/packages/react-graphql-universal-provider), [I18n](https://github.com/Shopify/quilt/tree/master/packages/react-i18n-universal-provider), and the [Shopify App Bridge](https://github.com/Shopify/quilt/tree/master/packages/react-app-bridge-universal-provider).
#### Customizing the node server
-By default, sewing-kit bundles in `@shopify/react-server-webpack-plugin` for `quilt_rails` applications to get apps up and running fast without needing to manually write any node server code. If what it provides is not sufficient, a custom server can be defined by adding a `server.js` or `server.ts` file to the app folder.
+By default, sewing-kit bundles in [`@shopify/react-server-webpack-plugin`](../../packages/react-server-webpack-plugin/README.md) for `quilt_rails` applications to get apps up and running fast without needing to manually write any node server code.
+If what it provides is not sufficient, a completely custom server can be defined by adding a `server.js` or `server.ts` file to the `app/ui` folder. The simplest way to customize the server is to export the object created by [`@shopify/react-server`](../../packages/react-server/README.md#node-usage)'s `createServer` call in `server.ts` file.
+
```
-└── app
+└── appeon
└── ui
└─- app.{js|ts}x
└─- index.{js|ts}
└─- server.{js|ts}x
```
-```tsx
-// app/ui/server.tsx
-import '@shopify/polyfills/fetch';
-import {createServer} from '@shopify/react-server';
-import {Context} from 'koa';
-import React from 'react';
+#### Fixing rejected CSRF tokens for new user sessions
-import App from './app';
+When a React component sends HTTP requests back to a Rails endpoint (e.g., `/graphql`), Rails may throw a `Can't verify CSRF token authenticity` exception. This stems from the Rails CSRF tokens not persisting until after the first `UiController` call ends.
-// The simplest way to build a custom server that will work with this library is to use the APIs provided by @shopify/react-server.
-// https://github.com/Shopify/quilt/blob/master/packages/react-server/README.md#L8
-const app = createServer({
- port: process.env.PORT ? parseInt(process.env.PORT, 10) : 8081,
- ip: process.env.IP,
- assetPrefix: process.env.CDN_URL || 'localhost:8080/assets/webpack',
- render: (ctx, {locale}) => {
- const whatever = /* do something special with the koa context */;
- // any special data we add to the incoming request in our rails controller we can access here to pass into our component
- return <App server someCustomProp={whatever} location={ctx.request.url} locale={locale} />;
- },
-});
+If your API **does not** require session data, the easiest way to deal with this is to use `protect_from_forgery with: :null_session`. This will work for APIs that either have no authentication requirements, or use header based authentication.
-export default app;
-```
+##### Example
-#### Fixing rejected CSRF tokens for new user sessions
+```rb
+class GraphqlController < ApplicationController
+ protect_from_forgery with: :null_session
-If a React component calls back to a Rails endpoint (e.g., `/graphql`), Rails may throw a `Can't verify CSRF token authenticity` exception. This stems from the Rails CSRF tokens not persisting until after the first `UiController` call ends.
+ def execute
+ # Get GraphQL query, etc
-To fix this:
+ result = MySchema.execute(query, operation_name: operation_name, variables: variables, context: context)
-- Add an `X-Shopify-Server-Side-Rendered: 1` header to all server-side GraphQL requests
-- Add a `protect_from_forgery with: Quilt::TrustedUiServerCsrfStrategy` override to Node-accessed controllers
+ render(json: result)
+ end
+end
+```
-e.g.:
+If your API **does** require session data, you may can use follow the following 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
+
```rb
class GraphqlController < ApplicationController
- protect_from_forgery with: Quilt::TrustedUiServerCsrfStrategy
+ protect_from_forgery with: Quilt::HeaderCsrfStrategy
def execute
# Get GraphQL query, etc
result = MySchema.execute(query, operation_name: operation_name, variables: variables, context: context)
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.