[App proxies](/docs/apps/online-store/app-proxies) take requests to Shopify links, and redirect them to external links. The `authenticate.public.appProxy` function validates requests made to app proxies, and returns a context to enable querying Shopify APIs. > Note: If the store has not installed the app, store-related properties such as `admin` or `storefront` will be `undefined`
import type {LoaderFunctionArgs} from '@remix-run/node';
import {authenticate} from '../shopify.server';
export const loader = async ({request}: LoaderFunctionArgs) => {
const {storefront, liquid} = await authenticate.public.appProxy(request);
if (!storefront) {
return new Response();
}
const response = await storefront.graphql(
`#graphql
query productTitle {
products(first: 1) {
nodes {
title
}
}
}`,
);
const body = await response.json();
const title = body.data.products.nodes[0].title;
return liquid(`Found product ${title} from {{shop.name}}`);
};
Authenticates requests coming to the app from Shopify app proxies.
request: Request
export type AuthenticateAppProxy = ( request: Request, ) => Promise<AppProxyContext | AppProxyContextWithSession>;
No session is available for the shop that made this request. This comes from the session storage which `shopifyApp` uses to store sessions in your database of choice.
No session is available for the shop that made this request. Therefore no methods for interacting with the GraphQL / REST Admin APIs are available.
No session is available for the shop that made this request. Therefore no method for interacting with the Storefront API is available.
A utility for creating a Liquid Response.
body: string
initAndOptions: number | (ResponseInit & Options)
export type LiquidResponseFunction = ( body: string, initAndOptions?: number | (ResponseInit & Options), ) => Response;
Whether to use the shop's theme layout around the Liquid content.
The session for the shop that made the request. This comes from the session storage which `shopifyApp` uses to store sessions in your database of choice. Use this to get shop or user-specific data.
Methods for interacting with the GraphQL / REST Admin APIs for the store that made the request.
Method for interacting with the Shopify Storefront Graphql API for the store that made the request.
A utility for creating a Liquid Response.
Stores App information from logged in merchants so they can make authenticated requests to the Admin API.
The unique identifier for the session.
The Shopify shop domain, such as `example.myshopify.com`.
The state of the session. Used for the OAuth authentication code flow.
Whether the access token in the session is online or offline.
The desired scopes for the access token, at the time the session was created.
The date the access token expires.
The access token for the session.
Information on the user for the session. Only present for online sessions.
Whether the session is active. Active sessions have an access token that is not expired, and has the given scopes.
Whether the access token has the given scopes.
Whether the access token is expired.
Converts an object with data into a Session.
Checks whether the given session is equal to this session.
Converts the session into an array of key-value pairs.
How long the access token is valid for, in seconds.
The effective set of scopes for the session.
The user associated with the access token.
The user's ID.
The user's first name.
The user's last name.
The user's email address.
Whether the user has verified their email address.
Whether the user is the account owner.
The user's locale.
Whether the user is a collaborator.
A class that represents a set of access token scopes.
Checks whether the current set of scopes includes the given one.
Checks whether the current set of scopes equals the given one.
Returns a comma-separated string with the current set of scopes.
Returns an array with the current set of scopes.
The unique identifier for the session.
The Shopify shop domain.
The state of the session. Used for the OAuth authentication code flow.
Whether the access token in the session is online or offline.
The scopes for the access token.
The date the access token expires.
The access token for the session.
Information on the user for the session. Only present for online sessions.
Omit<OnlineAccessInfo, 'associated_user'> & { associated_user: Partial<OnlineAccessUser>; }
Methods for interacting with the Shopify Admin REST API There are methods for interacting with individual REST resources. You can also make `GET`, `POST`, `PUT` and `DELETE` requests should the REST resources not meet your needs.
Methods for interacting with the Shopify Admin GraphQL API
RemixRestClient & {resources: Resources}
Performs a GET request on the given path.
Performs a POST request on the given path.
Performs a PUT request on the given path.
Performs a DELETE request on the given path.
The path to the resource, relative to the API version root.
The type of data expected in the response.
The request body.
Query parameters to be sent with the request.
Additional headers to be sent with the request.
The maximum number of times the request can be made if it fails with a throttling or server error.
Headers to be sent with the request.
Record<string, string | number | string[]>
GetRequestParams & { data: Record<string, any> | string; }
query: Operation extends keyof Operations
options: GraphQLQueryOptions<Operation, Operations>
export type GraphQLClient<Operations extends AllOperations> = < Operation extends keyof Operations, >( query: Operation, options?: GraphQLQueryOptions<Operation, Operations>, ) => Promise<GraphQLResponse<Operation, Operations>>;
The variables to pass to the operation.
The version of the API to use for the request.
Additional headers to include in the request.
The total number of times to try the request if it fails.
Method for interacting with the Shopify Storefront GraphQL API If you're getting incorrect type hints in the Shopify template, follow [these instructions](https://github.com/Shopify/shopify-app-template-remix/tree/main#incorrect-graphql-hints).
[App proxies](/docs/apps/online-store/app-proxies) take requests to Shopify links, and redirect them to external links. The `authenticate.public.appProxy` function validates requests made to app proxies, and returns a context to enable querying Shopify APIs. > Note: If the store has not installed the app, store-related properties such as `admin` or `storefront` will be `undefined`
import { json } from "@remix-run/node";
import { authenticate } from "../shopify.server";
import { getMyAppModelData } from "~/db/model.server";
export const loader = async ({ request }) => {
// Get the session for the shop that initiated the request to the app proxy.
const { session } =
await authenticate.public.appProxy(request);
// Use the session data to make to queries to your database or additional requests.
return json(
await getMyAppModelData({shop: session.shop})
);
};
import { json } from "@remix-run/node";
import { authenticate } from "../shopify.server";
export async function action({ request }: ActionFunctionArgs) {
const { admin } = await authenticate.public.appProxy(request);
const response = await admin.graphql(
`#graphql
mutation populateProduct($input: ProductInput!) {
productCreate(input: $input) {
product {
id
}
}
}`,
{
variables: {
input: { title: "Product Name" }
}
}
);
const productData = await response.json();
return json({ data: productData.data });
}
import { json } from "@remix-run/node";
import { authenticate } from "../shopify.server";
export async function action({ request }: ActionFunctionArgs) {
const { storefront } = await authenticate.public.appProxy(request);
const response = await storefront.graphql(
`#graphql
query blogIds {
blogs(first: 10) {
edges {
node {
id
}
}
}
}`
);
return json(await response.json());
}
import {authenticate} from "~/shopify.server"
export async function loader({ request }) {
const {liquid} = await authenticate.public.appProxy(request);
return liquid("Hello {{shop.name}}");
}
import {authenticate} from "~/shopify.server"
export async function loader({ request }) {
const {liquid} = await authenticate.public.appProxy(request);
return liquid(
"Hello {{shop.name}}",
{ layout: false }
);
}
import { redirect } from "@remix-run/node";
import { authenticate } from "~/shopify.server";
export async function loader({ request }) {
const { liquid } = await authenticate.public.appProxy(request);
return liquid(`
<form method="post" action="/apps/proxy/my-action">
<input type="text" name="field" />
<button type="submit">Submit</button>
</form>
`);
}
export async function action({ request }) {
await authenticate.public.appProxy(request);
const formData = await request.formData();
const field = formData.get("field")?.toString();
// Perform actions here
if (field) {
console.log("Field:", field);
}
// Return to the form page
return redirect("/apps/proxy/my-action");
}