Markkët ios client, discover new creators
Built with Expo + React Native + Expo Router.
- API base URL:
https://api.markket.place - Display base URL:
https://markket.place/
The app requests stores with logos from this path:
/api/stores?populate[]=Logo
- Install dependencies:
npm install- Start the app:
npx expo start- Open on iOS, Android, or web from Expo CLI.
- Start dev server:
npm run start - iOS:
npm run ios - Android:
npm run android - Web:
npm run web - Lint:
npm run lint
app/(tabs)/index.tsx: Home list of Markket storesapp/(tabs)/explore.tsx: Settings screenapp/store/[slug].tsx: Store WebView screenhooks/use-app-config.tsx: Persisted app config and URL settings
- If you change the API base URL in Settings, return to Home and pull to refresh.
- If you host your own instance, ensure CORS/network rules allow app access.
Store-scoped screens must always enforce store filters. If a filter is missing or malformed, Strapi may return global content from all stores.
- Always include a store slug filter for store-specific content.
- Never render results blindly. Validate that each returned item belongs to the active store.
- If store ownership cannot be confirmed, fail closed (show empty state), not open.
- Use fallback query variants only when still store-scoped.
Use slug as the active store slug.
- Stores:
/api/stores?filter[slug][$eq]=slug/api/stores?filters[slug][$eq]=slug
- Articles (blog):
/api/articles?filter[store][slug]=slug/api/articles?filters[store][slug]=slug
- Pages:
/api/pages?filter[store][slug]=slug&populate[]=SEO.socialImage/api/pages?filter[store][slug][$eq]=slug&populate[]=SEO.socialImage
- Products:
/api/products?filters[stores][slug][$eq]=slug
- Prefer explicit populate for required media fields (
cover,SEO.socialImage, etc.). - Avoid relying only on
populate=*for critical behavior. - Keep populate fallbacks, but keep store filter fixed in every attempt.
Before rendering cards in store-specific rails:
- Articles: verify
article.store.slug === activeSlugorarticle.stores[].slugcontainsactiveSlug. - Pages: verify
page.store.slug === activeSlugorpage.stores[].slugcontainsactiveSlug. - If relation fields are not populated, treat response as untrusted for strict filtering.
Some stores currently return mixed content formats:
- Plain Markdown strings
- Strapi Rich Text/Blocks JSON arrays (nodes with
type,children,text)
Current app behavior should remain format-tolerant:
- Do not assume
Contentis always Markdown. - Always normalize unknown content to safe preview text for cards/lists.
- Render Markdown parsing only when the source is confirmed string Markdown.
- For blocks JSON, flatten text nodes for previews and keep native detail rendering resilient.
Practical rule:
- If content type is uncertain, prefer safe text extraction over strict formatting.
- Copy the exact request URL used by the app.
- Test it directly in browser/curl.
- Confirm whether result items include store relation and matching slug.
- If not, fix filter first, then populate.
- Do not weaken store filter to "make data appear".