Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .changeset/violet-peaches-notice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
'@shopify/hydrogen': minor
---

The `enableStreaming` config option has been deprecated. The same feature can be done directly in the app:

```diff
// hydrogen.config.js

export default defineConfig({
shopify: {
// ...
},
- enableStreaming: (req) => {
- return req.headers.get('user-agent') !== 'custom bot';
- },
});
```

```diff
// App.server.jsx

-function App() {
+function App({request, response}) {
+ if (request.headers.get('user-agent') === 'custom bot') {
+ response.doNotStream();
+ }

return <Suspense fallback={'Loading...'}>{/*...*/}</Suspense>;
}

export default renderHydrogen(App);
```
21 changes: 0 additions & 21 deletions docs/framework/hydrogen-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ The following groupings of configuration properties can exist in Hydrogen:
- [`shopify`](#shopify)
- [`session`](#session)
- [`serverAnalyticsConnectors`](#serveranalyticsconnectors)
- [`enableStreaming`](#enablestreaming)
- [`logger`](#logger)

### `routes`
Expand Down Expand Up @@ -190,26 +189,6 @@ export default defineConfig({

{% endcodeblock %}

### `enableStreaming`

By default, all routes in Hydrogen are stream rendered. Stream rendering is automatically disabled when the user agent is a bot.

Content should be immediately available to bots for SEO purposes. However, you might want to manually disable streaming for a specific page. A common use case is disabling streaming for a custom bot that's not recognized by Hydrogen's bot detection algorithm. You can disable streaming for a custom bot with the `enableStreaming` configuration property:

{% codeblock file, filename: 'hydrogen.config.ts' %}

```tsx
import {PerformanceMetricsServerAnalyticsConnector} from '@shopify/hydrogen';
export default defineConfig({
enableStreaming: (req) => req.headers.get('user-agent') !== 'custom bot',
});
```

{% endcodeblock %}

> Tip:
> There are [performance benefits](https://shopify.dev/custom-storefronts/hydrogen/best-practices/performance) to streaming. You shouldn't completely disable streaming for all of your storefront's routes.

### `logger`

The default behavior of the [`log` utility](https://shopify.dev/api/hydrogen/utilities/log) maps to the global `console` object. However, you can also customize this behavior in the configuration object.
Expand Down
2 changes: 1 addition & 1 deletion docs/framework/preloaded-queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ const data = fetchSync('https://my.api.com/data.json', {

To test a preloaded query, enable the `logger.showQueryTiming` property in your [Hydrogen configuration file](https://shopify.dev/custom-storefronts/hydrogen/framework/hydrogen-config#logger).

The [`showQueryTiming`](https://shopify.dev/api/hydrogen/utilities/log#logger-options) property logs the timeline of when queries are being requested, resolved, and rendered. If a query is preloaded, but isn't being used, then a warning displays in the server log:
The [`showQueryTiming`](https://shopify.dev/custom-storefronts/hydrogen/framework/hydrogen-config#logger) property logs the timeline of when queries are being requested, resolved, and rendered. If a query is preloaded, but isn't being used, then a warning displays in the server log:

![Shows a screenshot of preloaded query warning](/assets/custom-storefronts/hydrogen/preload-query-warning.png)

Expand Down
5 changes: 4 additions & 1 deletion docs/framework/routes.md
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ export default function MyProducts({response}) {

#### `response.doNotStream()`

By default, Hydrogen [streams SSR responses](https://shopify.dev/custom-storefronts/hydrogen/framework/streaming-ssr). To customize a response, you need to tell Hydrogen that your server component plans to modify it in some way by calling `response.doNotStream()`:
By default, Hydrogen [streams SSR responses](https://shopify.dev/custom-storefronts/hydrogen/framework/streaming-ssr). However, you can also disable streaming for each route and return a fully buffered response. This is helpful in scenarios like [handling custom SEO bots](https://shopify.dev/custom-storefronts/hydrogen/framework/seo#checking-for-custom-robots). To disable streaming, call `response.doNotStream()`:

{% codeblock file %}

Expand All @@ -332,6 +332,9 @@ export default function CustomPage({response}) {

{% endcodeblock %}

> Tip:
> There are [performance benefits](https://shopify.dev/custom-storefronts/hydrogen/best-practices/performance) to streaming. You shouldn't completely disable streaming for all of your storefront's routes.

You can use `response` to set headers or status codes using the `Response` API:

{% codeblock file %}
Expand Down
28 changes: 25 additions & 3 deletions docs/framework/seo.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,33 @@ return (

{% endcodeblock %}

## Imitating SEO robot behavior
## SEO robot behavior

Hydrogen supports SEO by inspecting the `user-agent` for every request, and buffering the response to fully render it on server-side.
By default, all routes in Hydrogen are stream rendered. However, Hydrogen supports SEO by inspecting the `user-agent` for every request, disabling streaming, and buffering the response to fully render it on the server-side.

To imitate the behaviour of a SEO robot and show the page content fully from server render for initial render, add the `?\_bot` query parameter at the end of the webpage's URL.
### Imitating robot behavior

To imitate the behaviour of a SEO robot and show the page content fully from server render for initial render, add the `?_bot` query parameter at the end of the webpage's URL.

### Checking for custom robots

If you find a bot that's not recognized by Hydrogen's bot detection algorithm, you can [manually disable streaming](https://shopify.dev/custom-storefronts/hydrogen/framework/routes#response-donotstream) to buffer the response and make the content immediately available to bots:

{% codeblock file, filename: 'App.server.jsx' %}

```jsx
function App({request, response}) {
if (request.headers.get('user-agent') === 'custom bot') {
response.doNotStream();
}

return <Suspense fallback={'Loading...'}>{/*...*/}</Suspense>;
}

export default renderHydrogen(App);
```

{% endcodeblock %}

## Removing SEO with noindex

Expand Down
9 changes: 3 additions & 6 deletions packages/hydrogen/src/entry-server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,9 @@ export const renderHydrogen = (App: any) => {
});
}

const isStreamable =
(hydrogenConfig.enableStreaming
? hydrogenConfig.enableStreaming(request)
: true) && !isBotUA(url, request.headers.get('user-agent'));

if (!isStreamable) response.doNotStream();
if (isBotUA(url, request.headers.get('user-agent'))) {
response.doNotStream();
}

return runSSR({
log,
Expand Down
1 change: 0 additions & 1 deletion packages/hydrogen/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ export type InlineHydrogenConfig = {
serverAnalyticsConnectors?: Array<ServerAnalyticsConnector>;
logger?: LoggerConfig;
session?: (log: Logger) => SessionStorageAdapter;
enableStreaming?: (request: ServerComponentRequest) => boolean;
};

export type ResolvedHydrogenConfig = Omit<InlineHydrogenConfig, 'routes'> & {
Expand Down
3 changes: 0 additions & 3 deletions packages/playground/server-components/hydrogen.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ export default defineConfig({
session: CookieSessionStorage('__session', {
expires: new Date(1749343178614),
}),
enableStreaming: (req) => {
return req.headers.get('user-agent') !== 'custom bot';
},
logger: {
trace() {},
debug() {},
Expand Down
6 changes: 5 additions & 1 deletion packages/playground/server-components/src/App.server.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import Custom2 from './customRoutes/custom2.server';
import LazyRoute from './customRoutes/lazyRoute.server';
import ServerParams from './customRoutes/params.server';

export default renderHydrogen(() => {
export default renderHydrogen(({request, response}) => {
if (request.headers.get('user-agent') === 'custom bot') {
response.doNotStream();
}

return (
<Suspense fallback={'Loading...'}>
<ShopifyProvider>
Expand Down