Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions .env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/// <reference types="vite/client" />
/// <reference types="@react-router/node" />
1 change: 0 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
node_modules
build
public/build
shopify-app-remix
*/*.yml
.shopify
96 changes: 96 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/**
* This is intended to be a basic starting point for linting in your app.
* It relies on recommended configs out of the box for simplicity, but you can
* and should modify this configuration to best suit your team's needs.
*/

/** @type {import('eslint').Linter.Config} */
module.exports = {
root: true,
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
ecmaFeatures: {
jsx: true,
},
},
env: {
browser: true,
commonjs: true,
es6: true,
},
ignorePatterns: ["!**/.server", "!**/.client"],

// Base config
extends: ["eslint:recommended"],

overrides: [
// React
{
files: ["**/*.{js,jsx,ts,tsx}"],
plugins: ["react", "jsx-a11y"],
extends: [
"plugin:react/recommended",
"plugin:react/jsx-runtime",
"plugin:react-hooks/recommended",
"plugin:jsx-a11y/recommended",
],
settings: {
react: {
version: "detect",
},
formComponents: ["Form"],
linkComponents: [
{ name: "Link", linkAttribute: "to" },
{ name: "NavLink", linkAttribute: "to" },
],
"import/resolver": {
typescript: {},
},
},
},

// Typescript
{
files: ["**/*.{ts,tsx}"],
plugins: ["@typescript-eslint", "import"],
parser: "@typescript-eslint/parser",
settings: {
"import/internal-regex": "^~/",
"import/resolver": {
node: {
extensions: [".ts", ".tsx"],
},
typescript: {
alwaysTryTypes: true,
},
},
},
extends: [
"plugin:@typescript-eslint/recommended",
"plugin:import/recommended",
"plugin:import/typescript",
],
},

// Node
{
files: [".eslintrc.cjs"],
env: {
node: true,
},
},

// Node/Server files
{
files: [
"**/*.server.{js,jsx,ts,tsx}",
"vite.config.{js,ts}",
"app/routes/**/*.{js,jsx,ts,tsx}",
],
env: {
node: true,
},
},
],
};
13 changes: 0 additions & 13 deletions .eslintrc.js

This file was deleted.

4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ database.sqlite
.env
package-lock.json
yarn.lock

# Hide files auto-generated by react router
.react-router/
.shopify
3 changes: 2 additions & 1 deletion .graphqlrc.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const fs = require("node:fs");
const apiVersion = require("@shopify/shopify-app-remix").LATEST_API_VERSION;
const apiVersion =
require("@shopify/shopify-app-react-router").LATEST_API_VERSION;

function getConfig() {
const config = {
Expand Down
1 change: 0 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ build
node_modules
prisma
public
shopify-app-remix
.github
tmp
*.yml
Expand Down
18 changes: 7 additions & 11 deletions app/entry.server.jsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,25 @@
import { PassThrough } from "stream";
import { renderToPipeableStream } from "react-dom/server";
import { Response } from "@remix-run/node";
import { RemixServer } from "@remix-run/react";
import { ServerRouter } from "react-router";
import { isbot } from "isbot";

import { addDocumentResponseHeaders } from "./shopify.server";

const ABORT_DELAY = 5_000;
export const streamTimeout = 5000;

export default async function handleRequest(
request,
responseStatusCode,
responseHeaders,
remixContext,
_loadContext
context
) {
addDocumentResponseHeaders(request, responseHeaders);
const userAgent = request.headers.get("user-agent");
const callbackName = isbot(userAgent ?? "") ? "onAllReady" : "onShellReady";

return new Promise((resolve, reject) => {
const { pipe, abort } = renderToPipeableStream(
<RemixServer
context={remixContext}
url={request.url}
abortDelay={ABORT_DELAY}
/>,
<ServerRouter context={context} url={request.url} />,
{
[callbackName]: () => {
const body = new PassThrough();
Expand All @@ -51,6 +45,8 @@ export default async function handleRequest(
}
);

setTimeout(abort, ABORT_DELAY);
// Automatically timeout the React renderer after 6 seconds, which ensures
// React has enough time to flush down the rejected boundary contents
setTimeout(abort, streamTimeout + 1000);
});
}
12 changes: 2 additions & 10 deletions app/root.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
import {
Links,
LiveReload,
Meta,
Outlet,
Scripts,
ScrollRestoration,
} from "@remix-run/react";
import { Links, Meta, Outlet, Scripts, ScrollRestoration } from "react-router";

export default function App() {
return (
<html>
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
Expand All @@ -19,7 +12,6 @@ export default function App() {
<body>
<Outlet />
<ScrollRestoration />
<LiveReload />
<Scripts />
</body>
</html>
Expand Down
3 changes: 3 additions & 0 deletions app/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { flatRoutes } from "@react-router/fs-routes";

export default flatRoutes();
10 changes: 4 additions & 6 deletions app/routes/_index/route.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { json, redirect } from "@remix-run/node";
import { Form, useLoaderData } from "@remix-run/react";
import { redirect } from "react-router";
import { Form, useLoaderData } from "react-router";

import { login } from "../../shopify.server";

import indexStyles from "./style.css";

export const links = () => [{ rel: "stylesheet", href: indexStyles }];
import "./styles.css?url";

export async function loader({ request }) {
const url = new URL(request.url);
Expand All @@ -14,7 +12,7 @@ export async function loader({ request }) {
throw redirect(`/app?${url.searchParams.toString()}`);
}

return json({ showForm: Boolean(login) });
return { showForm: Boolean(login) };
}

export default function App() {
Expand Down
Loading