Coder Social home page Coder Social logo

carstenlebek / shopify-node-app-starter Goto Github PK

View Code? Open in Web Editor NEW
173.0 8.0 29.0 815 KB

๐Ÿš€๐Ÿš€ A Shopify embedded app starter template, written in TypeScript with session storage, app context and examples for basic functionalities.

Home Page: https://typescript-next-shopify-app.vercel.app

License: MIT License

Shell 0.03% JavaScript 0.46% TypeScript 99.51%
nextjs shopify shopify-app trpc typescript shopify-app-node

shopify-node-app-starter's Introduction

shopify-node-app-starter's People

Contributors

carstenlebek avatar reikje avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

shopify-node-app-starter's Issues

Cookies gone after app is embedded (without offline endpoints)

I removed the offline access tokens endpoint as my app won't need to contact Shopify API without the user consentiment.

So my middleware ends up like this:

    const urlParams = new URLSearchParams(req.url?.split('?')[1]);
    const {shop} = Object.fromEntries(urlParams);

    if (
        req.nextUrl.pathname.startsWith('/api/auth') ||
        req.nextUrl.pathname.startsWith('/api/webhooks')
    ) {
        return NextResponse.next();
    }

    if (req.nextUrl.pathname.startsWith('/api')) {
        return await withShopifyMiddleware(req, shop);
    }

    if (shop) {
        const shopSession = await findShopByShopDomain(shop)
        console.info(shopSession)

        if (!shopSession) {
            return NextResponse.redirect(
                `${process.env.HOST}/api/auth/?shop=${shop}`
            );
        }

        return NextResponse.next({
            headers: {
                'Content-Security-Policy': `frame-ancestors https://${shop} https://admin.shopify.com;`,
            },
        });
    }

    return NextResponse.next();

I also changed a few things here and there and now Cookies are gone after the app rich is embedded state and

   const bearerPresent = req.headers.get('authorization')?.match(/Bearer (.*)/);

is always undefined!

@carstenlebek Any thoughts on why this might append?

Perform fewer HTTP calls at the Callback Endpoint (Solution)

I've been playing around with Shopify OAuth a little bit again and I might discover a way of not doing too many requests into the callback endpoints.

I realised if I tweak a little bit the code of the session storage file, at the callback endpoint we would have to persist a second time the shop into Redis!

There are only two cases during Shopify OAuth that need to be handled! We know that Shopify uses session.id from the SessionInterface, the ID can vary between a uuidv4 string and the shop URL with a suffixed number like this: .myshopify.com_123456789.

Suffice to say, that we only need to handle the storeCallback and the loadCallback to make this work, let's see some code:

const SHOPIFY_DOMAIN = ".myshopify.com";

const storeCallback = async (session: SessionInterface): Promise<boolean> => {
  const result = await redis.set(
    session.id.includes(SHOPIFY_DOMAIN) ? session.shop : session.id,
    JSON.stringify(session),
    session.id.includes("offline") ? {} : { ex: 36000 }
  );

  return result === "OK";
};

const getShopDomainIfPresent = (shopId: string): string | null => {
  if (shopId.includes(SHOPIFY_DOMAIN)) {
    return shopId.substring(0, shopId.indexOf("_"));
  }

  return null;
};

const loadCallback = async (shopId: string): Promise<SessionInterface | { [key: string]: unknown } | undefined> => {
  const result = await redis.get<Promise<SessionInterface | null>>(getShopDomainIfPresent(shopId) || shopId);

  return result ?? undefined;
};

const deleteCallback = async (shopId: string): Promise<boolean> => {
  const result = await redis.del(getShopDomainIfPresent(shopId) || shopId);

  return result > 0;
};

By doing this, this piece of code is now obsolete benefiting from fewer calls at the callback endpoint!

      const redis = new Redis({
        url: process.env.UPSTASH_REDIS_REST_URL as string,
        token: process.env.UPSTASH_REDIS_REST_TOKEN as string
      });

      const redisShop = await redis.get(session.shop);
      if (!redisShop || redisShop !== process.env.SCOPES) {
        await redis.set(session.shop, session);
      }

Abort [Error]: The CLIKitStore instance hasn't been initialized & AppBridgeError: APP::ERROR::INVALID_CONFIG: host must be provided

Hey guys.
Unfortunately, it is not possible to set up the project due to two errors. Been trying to get the project to run for hours.

Error 1: Abort [Error]: The CLIKitStore instance hasn't been initialized - The CLIKitStore instance hasn't been initialized in line 35 @ next.config.mjs before session.ensureAuthenticatedPartners(); is called. I couldn't find any documentation on @shopify/cli-kit and trying await store.initializeCliKitStore(); in line 34 doesn't seem to work either. How do I initialize the store before the session is authenticated?

Error 2: AppBridgeError: APP::ERROR::INVALID_CONFIG: host must be provided - Whether I comment out the host in line 62 @ next.config.mjs or not, the host seems to be non-resolvable. Do I need to define an additional host in the dotenv? HOST=https://localhost does not seem to work for me, even tho I set it as URL in the Shopify Plugin. Is there a solution for this?

I would be very grateful for any solutions and advice and thank you in advance.

Have a nice evening everyone :)

Error when running npm run dev

Hi!
After following all the steps, when running npm run dev, the software runs into an error. Output is:

ready - started server on 0.0.0.0:3000, url: http://localhost:3000
info  - Loaded env from [my-path]\.env
Abort [Error]: The CLIKitStore instance hasn't been initialized
    at cliKitStore (file:///[MY-APP-PATH]/node_modules/@shopify/cli-kit/dist/store.js:28:15)
    ......

Ani ideas why that is?

Breaking changes in @shopify/[email protected]

Firstly, thanks for this fantastic template. However, there are some breaking changes to the structure of the @shopify/cli-kit package introduced in it's 3.40.0 (minor?) version which are preventing the app from starting for npm users (since you only have a pnpm-lock.yml in the template).

error - Failed to load next.config.mjs, see more info here https://nextjs.org/docs/messages/next-config-error
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/REDACTED/shopify-node-app-starter/node_modules/@shopify/cli-kit/dist/index.js' imported from /Users/REDACTED/shopify-node-app-starter/next.config.mjs
    at new NodeError (node:internal/errors:387:5)
    at finalizeResolution (node:internal/modules/esm/resolve:330:11)
    at moduleResolve (node:internal/modules/esm/resolve:907:10)
    at defaultResolve (node:internal/modules/esm/resolve:1115:11)
    at nextResolve (node:internal/modules/esm/loader:163:28)
    at ESMLoader.resolve (node:internal/modules/esm/loader:841:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:424:18)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:76:40)
    at link (node:internal/modules/esm/module_job:75:36) {
  code: 'ERR_MODULE_NOT_FOUND'

My workaround was simply to specify the 3.13.0 version locally, but hopefully this issue will help others in a similar situation.

"cliKitStore.initializeCliKitStore is not a function" error

Received this error after running pnpm install and npm run on a new clone of the project. Using version 3.0.25 of @shopify/cli-kit.

TypeError: cliKitStore.initializeCliKitStore is not a function
    at setEnvironmentAndReturnHost (file:///Users/user/app/next.config.mjs:37:21)
    at config (file:///Users/user/app/next.config.mjs:66:18)
    at Object.normalizeConfig (/Users/user/app/node_modules/.pnpm/[email protected]_biqbaboplfbrettd7655fr4n2y/node_modules/next/server/config-shared.ts:556:14)
    at Object.loadConfig [as default] (/Users/user/app/node_modules/.pnpm/[email protected]_biqbaboplfbrettd7655fr4n2y/node_modules/next/server/config.ts:799:6)
    at NextServer.prepare (/Users/user/app/node_modules/.pnpm/[email protected]_biqbaboplfbrettd7655fr4n2y/node_modules/next/server/next.ts:110:20)
    at /Users/user/app/node_modules/.pnpm/[email protected]_biqbaboplfbrettd7655fr4n2y/node_modules/next/cli/next-dev.ts:107:

Console log of cliKitStore:

cliKitStore [Object: null prototype] {
  createConf: [Function: createConf],
  remove: [Function: remove$2],
  getAppInfo: [Function: getAppInfo],
  setAppInfo: [Function: setAppInfo],
  clearAppInfo: [Function: clearAppInfo],
  getTheme: [Function: getTheme],
  setTheme: [Function: setTheme],
  getSession: [Function: getSession],
  setSession: [Function: setSession],
  removeSession: [Function: removeSession]
}

I think I broke the app dev :D

Hello! Thanks for the awesome work, in case you know what's up, I tried to add cli3 inside the app and then I completely destroyed it.

When running the npm run dev I get , Variable $applicationUrl of type Url! was provided invalid value: {"response":{"errors":[{"message":"Variable $applicationUrl of type Url! was provided

Its around this line
ShopifyCli.mjs file
const result = await api.partners.request(query, token, variables);

Although all the strings are looking ok it expects a type of URL

I removed everything and the folders, cloned again etc, I installed everything again with force and npm audit fix but no luck.
Let me know if you have any idea! Thanks

Embedded app does not render

After successfully installing the app in our Shopify dev store, I am having issues getting the embedded app to actually render.

I see the follow error, and the browser URL contains the querystring params &oauth_error=same_site_cookies&before=&after=&tab=installed

image

Do you know what might be causing this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.