vendure-ecommerce / storefront-qwik-starter Goto Github PK
View Code? Open in Web Editor NEWAn e-commerce storefront starter built with Qwik and Vendure
Home Page: https://qwik-storefront.vendure.io
An e-commerce storefront starter built with Qwik and Vendure
Home Page: https://qwik-storefront.vendure.io
It will be awesome use graphql-codegen to generate schemas and types
To reproduce:
The main home page shows an error:
VITE v4.2.1 ready in 924 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
➜ press h to show help
4:49:47 AM [vite] Error when evaluating SSR module /src/env.ts:
4:49:47 AM [vite] Error when evaluating SSR module /src/utils/index.ts:
4:49:47 AM [vite] Error when evaluating SSR module /src/utils/api.ts:
4:49:47 AM [vite] Error when evaluating SSR module /src/graphql-wrapper.ts:
4:49:47 AM [vite] Error when evaluating SSR module /src/providers/checkout/checkout.ts:
4:49:47 AM [vite] Error when evaluating SSR module /.../qwik+storefront/src/routes/layout.tsx:
4:49:47 AM [vite] Internal server error: [
{
"code": "invalid_type",
"expected": "string",
"received": "undefined",
"path": [
"VITE_SECURE_COOKIE"
],
"message": "Required"
}
]
File: /.../qwik+storefront/node_modules/zod/lib/index.mjs:537:31
535| if (this._error)
536| return this._error;
537| const error = new ZodError(ctx.common.issues);
| ^
538| this._error = error;
539| return this._error;
at get error [as error] (file:///.../qwik+storefront/node_modules/zod/lib/index.mjs:537:31)
at ZodObject.parse (file:///.../qwik+storefront/node_modules/zod/lib/index.mjs:636:22)
at /.../qwik+storefront/src/env.ts:12:42
at async instantiateModule (file:///.../qwik+storefront/node_modules/vite/dist/node/chunks/dep-79892de8.js:53996:9)
Need to change the markup for the Cart Button in upper right hand corner:
0 items in cart
to reflect count of added items to cart.From MDN A11y docs:
Content with images must be labeled
Provide descriptive text for all contentful (that is, non-decorative) images and image-like elements. This includes SVG images, , , , and elements, as well as elements where type=image and elements where the type starts with image/. The typical way to do this is with the alt attribute. Be sure that the description conveys what is shown in the image.
Example
Interactive elements must be labeled
If an element is intended for users to interact with it, it should have a label. Interactive elements include links (), form elements, buttons, and any element that has a handler for mouse or keyboard events. The way to label an element depends on its type: for form elements, use a ; for links, buttons and clickable elements, the text content of the element typically provides the label. If no other option exists for labeling an element, use the aria-label attribute.
Currently, website unfurls (embeds) are the same for every link:
However, they could be better through personalized tags in each page's <head>
. I can recommend this resource: https://medium.com/slack-developer-blog/everything-you-ever-wanted-to-know-about-unfurling-but-were-afraid-to-ask-or-how-to-make-your-e64b4bb9254
Doesnt seem to get cached properly? If you cycle through with arrow-keys the whole thing updates wrong and jumps around.
If you want to see it in its glory just hold down arrow-down for a higher repeat-speed, then its completely broken.
Hello!
I'm relatively new to graphQL powered UIs, so doing "npm run generate" to get the graphQL API generated wasn't the first thing I could think of when starting the local server for the first time.
I noticed the issue when trying to get to the checkout page, it claimed that the "sdk" was undefined in "providers/orders/order.ts"
Suggested Fixes:
Unrelated note: Many thanks for your great work on this! I've been closely following your progress for the past few weeks. Amazing work done so far!
When trying to run the apllication getting the error [vite] Internal server error: fetch failed
[vite] Internal server error: fetch failed at Object.fetch (node:internal/deps/undici/undici:11457:11) at processTicksAndRejections (node:internal/process/task_queues:95:5) at runNextTicks (node:internal/process/task_queues:64:3) at process.processImmediate (node:internal/timers:447:9) at async executeRequest (C:\saneesh\projects\vendure\storefront-qwik-starter\src\utils\api.ts:51:23) at async execute (C:\saneesh\projects\vendure\storefront-qwik-starter\src\utils\api.ts:30:5) at async Module.getCollections (C:\saneesh\projects\vendure\storefront-qwik-starter\src\providers\collections\collections.ts:6:9) at async Object.useCollectionsLoader_routeLoader_7EpNZDTiNAI (C:\saneesh\projects\vendure\storefront-qwik-starter\src\routes\layout.tsx:23:9) at async Object.invokeQRL (C:\saneesh\projects\vendure\storefront-qwik-starter\dist-dev\tsc-out\packages\qwik\src\core\util\implicit_dollar.js:8177:24) at async measure (file:///C:/saneesh/projects/vendure/storefront-qwik-starter/node_modules/@builder.io/qwik-city/vite/index.mjs:24181:12)
I have added the braintree plugin as suggested on vendure, and used it as a payment method from vendure admin.
I see a "pay with braintree" button on my front end, enter the credit card etc.. but when I hit the pay button I get the following:
Uncaught (in promise) TypeError: res is null
addPaymentToOrderMutation checkout.ts:28
checkout.ts 28:44 -->
export const addPaymentToOrderMutation = async (
input: PaymentInput = { method: 'standard-payment', metadata: {} }
) => {
return sdk
.addPaymentToOrder({ input })
.then((res: AddPaymentToOrderMutation) => res.addPaymentToOrder as Order); <--- line 28
};
Any thoughts? I definitely have the braintree plugin setup and have synchronized the vendure database... so I assume this is an issue here? Also checked my generated folder and graphql matches latest - I only setup this project maybe a week or so ago. Happy to test anything else out
Noted on Vendure Server:
1|vendure | [server] warn 7/14/23, 9:48 PM - [Vendure Server] The orderId argument to the generateBraintreeClientToken mutation has been deprecated and may be omitted.
1|vendure | [server] warn 7/14/23, 9:48 PM - [Vendure Server] USER_INPUT_ERROR: error.payment-method-not-found
While browsing to the demo (which is impressively fast) I noticed that directly accessing a product page like:
https://qwik-storefront.vendure.io/products/laptop/
Breaks functionality of the Add to cart
button and of the header button to open the shopping cart (session data is also lost).
None of the above happens when browsing through the main page.
To be customisable we need to use env variables
These are some variables:
Even I tried on official demo site https://qwik-storefront.vendure.io and all links are not working. I use safari V14.
ReferenceError: Can't find variable: SubmitEvent
When I click on a sub collection the url is updated, but the content doesn't change
Hello sir, although I am not a developer, I was able to install it on a VPS with a Node.js adapter by reading the instructions. It is really very fast, well-featured, and easy to install. I did not find any issues. However, I have three concerns:
Hello,
I can't get Stripe to work.
I have two SSL demo servers:
Vendure :
storefront-qwik-starter :
When it's time to pay, I get this error :
Error: This API call cannot be made with a publishable API key. Please use a secret API key. You can find a list of your API keys at https://dashboard.stripe.com/account/apikeys.
(I did fill in these fields in Vendure Admin UI)
I don't understand a word ...
Does anyone have any ideas?
Thanks
I tried uploading a file but it didn't work with GraphQLs generic-sdk. It took me a full day to debug this. So far I haven't gotten to a way to do this via generic-sdk but managed to find a workaround (below):
overwrite: true
schema:
- "https://example.com/api"
# This is the additional schema extension that would be present if
# the Stripe playment plugin is enabled on the Vendure server. Added
# manually here to allow codegen to work regardless.
- "type Mutation { createStripePaymentIntent: String }"
documents:
- "src/providers/shop/**/*.{ts,tsx}"
- "!src/generated/*"
generates:
src/generated/graphql-shop.ts:
config:
enumsAsConst: true
plugins:
- typescript
- typescript-operations
- typescript-generic-sdk
src/generated/schema-shop.graphql:
plugins:
- schema-ast
// Note - I use qwik's noSerialize since this will be in a store, to be used across routes client-side.
// I tried uploading the blob before using noSerialize, same issue (below)
const imageBlob = noSerialize(await canvasToBlob(canvasEl.value!));
const filename = `preview_${new Date().getTime()}.png`;
const assetFile = new File([imageBlob as BlobPart], filename, { type: 'image/png' });
const res = await uploadAssetsMutation({
input: { assets: [assetFile], someCustomId: customId.id }
}, {
apiUrl: 'https://example.com/api',
channelToken: 'sample-channel-token'
});
canvasToBlob is just a helper function to use async-await instead of a callback with the canvas toBlob() function:
function canvasToBlob(canvas: HTMLCanvasElement): Promise<Blob> {
return new Promise((resolve, reject) => {
canvas.toBlob((blob) => {
if (blob) {
// if blob creation was successful
resolve(blob);
} else {
// if blob creation failed
reject(new Error('canvas.toBlob() error'));
}
});
});
}
The error I get is as follows
{1 item
"errors": [1 item
0:{. 2 items
"message":"Variable "$input" got invalid value {} at "input.assets[0]"; Upload value invalid."
"extensions":{1 item
"code":"BAD_USER_INPUT"
}
}
]
}
** WORKAROUND **
I could get around this by using the Apollo upload client
import { ApolloClient, InMemoryCache } from '@apollo/client/core';
const UPLOAD_MUTATION = gql`
mutation uploadPreview($input: SomeInput!) {
uploadPreviewAssets(input: $input) {
id
width
height
name
preview
focalPoint {
x
y
}
}
}
`;
const client = new ApolloClient({
link: createUploadLink({
uri: 'https://example.com/api',
headers: { "vendure-token": 'some-token'}
}),
cache: new InMemoryCache(),
});
client
.mutate({
mutation: UPLOAD_MUTATION,
variables: {
input: {
assets: [assetFile],
someEntityId: someEntity.id,
},
},
})
.then((result) => console.log('uploaded preview image:', result))
.catch((error) => console.error('Couldnt upload preview img:', error));
I looked through the-guild.dev for solutions but couldn't find any that worked. Anyone else facing issues with uploads here?
Reproduction steps:
Depends on #44
I hope this message finds you well. I am reaching out to you regarding an issue I have encountered while attempting to update user profile information within our application. I would like to share the details of the problem along with the error messages I have encountered.
Problem Description:
When I try to modify user information such as name, first name, email address, and phone number in the application, the changes are not being saved to the database. I have followed the appropriate steps to perform the update, but the modifications are not being reflected on the server side.
Steps Taken:
I log into the application as a user.
I navigate to the "Profile" section where I can edit my personal information.
I modify the name, first name, email address, and/or phone number.
I click the "Save" button to apply the changes.
Encountered Error Messages:
I have also come across the following error messages in the console during my update attempts:
Uncaught (in promise) Error: Variable "$input" got invalid value... Field "id" is not defined by type "UpdateCustomerInput".
Loading translations...
Error [ERR_STREAM_DESTROYED]: Cannot call write after a stream was destroyed
Lighthouse A11y score catches the following issue:
id
to the label and aria-labelledby
attribute to the input element should fix.is there a way to pass the locale value of "extractLang(request.headers.get('accept-language'), request.url)" to shop-api call?
i have tried something like this, but a error raised: "Internal server error: Reading locale
outside of context."
const executeRequest = async (options: Options) => {
const locale = getLocale();
const httpResponse = await fetch(`${ENV_VARIABLES.VITE_VENDURE_PUBLIC_URL}/?languageCode=${locale}`, options);
return await extractTokenAndData(httpResponse);
};
I found debugging API fetches hard because of 2 things:
For #1, I did the following inside the execute function, which decides where the call goes (server or client)
const response: ResponseProps<R> = isBrowser && !import.meta.env.DEV
? await executeOnTheServer(requestOptions, options.apiUrl!)
: await executeRequest(requestOptions, options.apiUrl!);
For #2 I'm trying to find the best way to handle this. Exposing errors to the app should be safe, for the app to translate what the error should mean to the end user. I just have to find a way to get this data to my components/routes. If you have ideas let me know.
Add 'alt' attribute to Img
tags. Maybe I need to add a name or description to the GQL query for each Product in the rendered collection? Then I can pull that product name/description and drop it in the alt attribute in the CollectionCard component.
From MDN:
Content with images must be labeled
Provide descriptive text for all contentful (that is, non-decorative) images and image-like elements. This includes SVG images, , , , and elements, as well as elements where type=image and elements where the type starts with image/. The typical way to do this is with the alt attribute. Be sure that the description conveys what is shown in the image.
Example
Would be useful for some direction on how to proceed with this project. As being new to qwik and vendure its a lot for me.
Example:
For others: to get network access, modify package.json:
so that "start" is now:
vite --open --mode ssr --host 0.0.0.0
(host is added).
Now I know that not everyone needs that, but next steps via building for production would be useful, especially how to add https to the site etc.... It would be just nice to have a little more hand holding to get things up and running properly.
I appreciate the project and it looks really cool, but definitely having trouble trying to get something working for me.
For some reason I can't create an account even though afaik I have connected to my own vendure instance using the ".env" file.
I get the following at user registration:
Account registration is not supported by the demo Vendure instance. In order to use it, please connect to your own local / production instance.
Currently, all pages have the title "Vendure Qwik Storefront". This should change depending on the page. So the "electronics" collection should reflect the collection name in the title, and the "laptop" product should likewise have the product name in the title.
Furthermore, we should incorporate metadata for open graph including images (where available, like on the product page) and descriptions (where available). This allows us to provide richer previews when sharing links.
Header does not stick when scrolling, even though I see tailwind css for it. Trying to find the bug, usually overflow, but I can't find it.
Other stores are also having this issue (remix/angular - although theirs are a little more buggy).
Hi @gioboa
Currently all labels are displayed by default in English, so it would be great to add i18n support to the starter.
I was taking a look at the Qwik community and there's a good approach to handle this:
https://github.com/mhevery/qwik-i18n
Initially, I would like to add support for English and Spanish languages. Let me know if you're ok if I grab this work.
To prevent regressions I think we must have e2e tests for the core flow
The can create a GH action to run this tests automatically
Currrently internal navigations do full page reloads. Per Giorgio there was an issue with the Link component at some point - it needs to be checked in the latest Qwik City to see if we can implement SPA mode nav.
I have a current issue where if you change the quantity in cart > then the stock available the item disappears from cart. Refreshing I get the maximum available. ie: I select "8" but only have "5", when I refresh I find "5" but in the meantime it disappears and doesn't let me "add to cart" (insufficient stock).
Desired solution: perhaps allow a dropdown which matches number of stock? or textfield? or at least min(stock,8) of options?
Perhaps a textfield with arrow buttons? Not sure what the correct approach is here, ideas?
Please accept and mark as with a lable of enhancement .
With npm i
and npm run dev
app showing this error
[vite] Internal server error: fetch is not a function
After npm run build
I used npm run serve
but this time I got another error:
npm run serve
npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.
> serve
> node server/entry.express.js
node:internal/modules/cjs/loader:936
throw err;
^
Error: Cannot find module 'C:\Test\qwik\storefront-qwik-starter\server\entry.express.js'
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
at Function.Module._load (node:internal/modules/cjs/loader:778:27)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
at node:internal/main/run_main_module:17:47 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
"express": "4.18.1", is in my devDependencies
"Password change" and "Account details" have this strange behavior
https://qwik-storefront.vendure.io/account/
https://qwik-storefront.vendure.io/account/password/
Vendure v2 is now in beta, so we can start taking a look at the work that needs to be done.
Remix storefront progress
vendure-ecommerce/storefront-remix-starter#40
Vendure V2.0 migration
vendure-ecommerce/vendure#1991
Currently, direct GraphQL calls are being made from the client to the Vendure server. We should instead set up Qwik City API routes to handle these, so all calls to Vendure go via the server.
This will simplify session management and also allow us to server-render even client-specific data.
An update must have broken something because the website no longer works, it only displays this error message
TypeError: method.toUppercase is not a function
Npm/Yarn start works fine, but when trying to run "preview" (and disabling minification so error is not gibberish) I'm getting "ReferenceError: Cannot access 'serverQrl' before initialization".
Almost every instance of serverQrl is in autogenerated js files so it's either a qwik/npm bug (Unlikely - everything worked fine when I tried running "preview" on the example qwik app), a problem with configuration, or a problem with adding qwik's lazy-loading where it doesn't fit,
P.S. This is the first qwik app I'm trying, so I'm not sure what else should I check for a better bug report (if you need more info, please say what I need to send)
Hello!
I found the following error while trying out the store, here's how you can replicate:
The error says "must be non null".
Hi @gioboa, I want to continue working on the Spanish translation.
I would like to continue with the checkout page. Is it ok for you?
This is a suggestion: I moved from codegen.yml to codegen.ts to be able to pass flags and use them to determine the graphQL API to call (local vs dev vs prod). See below (this pulls the shop API only)
import type { CodegenConfig } from '@graphql-codegen/cli';
const DEV_API = 'https://api-test.example.com/shop-api';
const PROD_API = 'https://api.example.com/shop-api';
const LOCAL_API = 'http://localhost:3000/shop-api';
const GRAPHQL_API = import.meta.env.IS_DEV ? DEV_API :
import.meta.env.IS_LOCAL ? LOCAL_API : PROD_API;
const config: CodegenConfig = {
schema: [
GRAPHQL_API,
'type Mutation { createStripePaymentIntent: String }'
],
documents: [
'"src/providers/shop/**/*.{ts,tsx}"',
'!src/generated/*'
],
generates: {
'src/generated/graphql-shop.ts': {
config: {
enumsAsConst: true
},
plugins: [
'typescript',
'typescript-operations',
'typescript-generic-sdk',
]
},
'src/generated/schema-shop.graphql': {
plugins: ['schema-ast']
}
}
}
export default config
Then in package.json, I have different scripts, one for each environment, e.g.:
{
...
scripts: {
"generate-admin": "graphql-codegen --config codegen-admin.ts",
"generate-shop": "graphql-codegen --config codegen-shop.ts",
"generate-dev": "IS_DEV=TRUE && npm run generate-shop && npm run generate-admin",
"generate-local": "IS_LOCAL=TRUE && npm run generate-shop && npm run generate-admin",
"generate": "npm run generate-shop && npm run generate-admin",
}
}
If you think converting .yml to .ts is better for everyone, I can create a pull request to merge it into main.
Thanks
When navigating from any page to another, the page scrolls to top THEN the new page is displayed.
This doesn't look right / feels buggy.
I tried commenting out the window.scrollTo(0, 0); in scrollToTop() in utils/index.ts - that didn't help. Still getting this weird behaviour.
In case you want to see it clearly (in Chrome):
This can be good also for the marketing and social activities
I will work on it 🚀
Check the Remix storefront for an example.
Depends on #44
Deploy to CloudFlare Pages
qwik-insights.builde…2fwnm5u5bvt/post/:1 | Failed to load resource: net::ERR_BLOCKED_BY_CLIENT |
---|
PLease help, thanks much
Hi, do you have any documentation for creating a component that queries products by category?
Thanks,
Best regards
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.