Repository navigation
Conversation
The versions npx expo install --check expects for SDK 58, plus what expo-router 58 needs for its testing peer: @testing-library/react-native 14, which renders with test-renderer instead of react-test-renderer, and Jest 30 with jest-expo 58. Dependencies outside the SDK keep their versions. The tests move to the async render APIs in the next commits. Refs #134 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ypes - The root stack is anchored with unstable_settings.anchor; initialRouteName is deprecated. - The first screen of (app) always has its back button, and it decides when pressed: Back, or Home when there is nothing to go back to. Its options are read once, before the stack below has settled, so the old check left a pushed Profile without a back button. (auth) uses the same router as the rest of the app. - "Go home" tries replace even when dismissTo throws, which it does before the navigator has rendered. - The password field's ref is a TextInputInstance, and the tab icons take the tab bar's tint colors: React Native's strict types reject the old ref type and React Navigation's ColorValue. Refs #134 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
render, renderHook, renderRouter, fireEvent and act return promises and are awaited. The UNSAFE_ queries are gone, and the test renderer keeps only host elements: screens' titles are read through a DocumentTitle stand-in (testing/documentTitle.tsx), and the StatusBar and KeyboardAvoidingView props from the components themselves. An awaited render has already settled what was ready, so tests that check a loading state hold the request or the storage read. The tab error-boundary tests replace the declared Home tab, since a Tabs layout only routes the screens it declares. jest.setup mocks the asset registry expo-asset now reads. Testing docs describe the async APIs. Refs #134 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
web.output was unset, and Expo SDK 58 changes what an unset value exports. Set it to 'single', which the hosting docs describe, and test it. Getting Started notes that the JavaScript is now split per route. Refs #134 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Android e2e downloads Expo Go 58.0.4 (SHA256 from the release's asset digest). The README, AGENTS.md, Getting Started and Testing name SDK 58, React Native 0.88 and React 19.3; Xcode 26.4+ is still the requirement. Refs #134 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Expo Router 58 renders a guarded screen as a Redirect, which calls
replace('/'): the root stack swaps the guarded group for a new Home
instead of returning to the Home below. Each sign-in and sign-out added
one more (3, 5, 7 after each round), a refused cold-start deep link left
two, and Back on Android or the iOS edge swipe showed Home again. The
root navigator now dismisses back to the bottom Home when the root stack
holds only Homes. Tests cover repeated sign-in and sign-out, the refused
deep links, and Profile's back button returning to a screen other than
Home.
Refs #134
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On Expo Router 58 a file in (tabs) without a Tabs.Screen is not a tab: no button, and links to it stay on Home (Conventions said it showed its file name). The web export now loads each route's JavaScript on demand, so Getting Started says to keep the previous deploy's _expo/static files and not to answer missing /_expo/ paths with index.html. Testing lists testing/documentTitle.tsx and rerender/unmount among the async APIs; the web.output comment no longer claims a server default. Refs #134 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ser Home 51d8e04 collapsed a root stack of only Homes, but Login or Profile opened over another screen still left a new Home on top: signing in from Login opened over Settings landed on Home, not Settings, and Back showed Settings and then Home again; signing out, or a session that ended, on Profile over Settings did the same. Expo Router 58 puts that new Home in the guarded group's place with replace('/'). The root navigator now pops a Home that is on top of the root stack above its bottom, which returns the user to the screen below, as on SDK 57. Tests cover sign-in, sign-out and an expired session over another screen. Refs #134 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Refs #134 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
60e0c35 popped any Home on top of the root stack above its bottom, but Expo Router 58 also puts one there for router.navigate, router.push and <Link> to a tab from a screen above the tabs: those did nothing at all. The root navigator now pops a Home only where (auth) or (app) just was, with the stack no longer: the guards' replace('/'). Tests cover navigate and push to Home from Settings, push to Home from Profile, and replace with a tab. Refs #134 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
83b66e5 recognised the guards' replace('/') by the stack alone, and the app's own replace from Login or Profile has the same shape: a Profile or Login button that replaced the screen with Explore landed on Home, and a replace with Home from Profile over Settings went back to Settings. The root navigator now pops the new Home only when the session changed while a guarded group was on top, and the Home is on its first tab. Guarded groups are listed in GUARDED_GROUPS. Tests cover Profile's own replace with Home, and Profile's and Login's own replace with a tab. Refs #134 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nt case R5's mutation testing found conditions no test needed: the same-top return (sign-out or expiry on a second (app) screen above Profile left two Homes without it), the (tabs) and length checks (signing in and at once replacing with a root screen, or pushing Home), the group check (another screen's own replace with Home after a sign-out), and the Home tab check (signing in and at once replacing Login with Explore, a demo test). Each now has a test. The first-state exception was equivalent to clearing the flag, so it goes. Refs #134 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ace after signIn Refs #134 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…o it at once
R6: the hook can't tell the app's own replace('/') right after a session
change from the guards' redirect, so it undid it, and a user who signed
out on Profile opened from Settings stayed on Settings. Conventions now
says to go Home with dismissTo('/'), and to navigate before awaiting
anything else, since the guards' redirect replaces what is on top then.
Tests cover dismissTo after signing in and out over Settings. The hook's
comment says so too, and a flag reset that the next state always repeats
goes.
Refs #134
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…other R7: the flag reset dropped in 5fb2731 was needed. Signing in on Login and at once replacing it with Profile (as Conventions advises) moves from one guarded group to the other, where no other reset runs, so a later replace('/') on Profile was taken for the guards' redirect and the user landed on the screen below instead of Home. The reset is back with a test. Conventions now says to go to a tab with dismissTo('/<tab>'), and to use replace only for screens outside (tabs): a replace with a tab adds a second Home. Refs #134 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…arded groups R8: the advice held on Login and Profile, but not for signIn/signOut on a tab such as Home's Sign out: there is no redirect there, dismissTo doesn't switch tabs, and replace drops Home. The paragraph is now its own, names where the guards' redirect happens, and says to navigate as usual elsewhere. Refs #134 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the tabs
R9: "navigate as usual" after a sign-out held on a tab, but on a screen
pushed over the tabs (an app/settings.tsx with Sign out) navigate('/')
and <Link> push a second Home, whatever the session does: Expo Router
58's behaviour. Conventions now states the general rule (dismissTo, or
back when the tab is just below) and points the sign-in paragraph to it;
"the screen below" is the screen below the group. The (app) layout's
comment said a user is sent Home when the session ends; it is the screen
below the group.
Refs #134
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… LOWs) Refs #134 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Owner
Author
|
Ready for review; not to be merged until the maintainer decides (#134 criterion 8). Evidence: https://github.com/koniz-dev/react-native-starter/tree/evidence/docs/evidence/issue-134 |
) Refs #134 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A restore that resolves after sign-in or expiry must not overwrite the session; without a test, dropping `!changedRef.current` left the whole suite green. The new tests also take every guard arm in SessionProvider (branch coverage 83% -> 100%), including refreshUser after expiry. Refs #136 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
zod before 4.6.6 can exhaust memory validating a large array of invalid items; the app parses backend arrays with z.array (demo todos, and the pattern Connect Your Backend teaches). The floor is now ^4.6.7, so the direct dependency can't resolve to an affected version. The advisory stays reported on zod 3 under @expo/cli (dev server only, no zod 3 fix): reviewed in the allowlist. The braces entry is removed: npm no longer reports it. Refs #142 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
eas.json has build and submit profiles, but no workflow used them. The EAS Build (manual) workflow takes a profile and platform, builds on EAS, and can auto-submit a production build. Without an EXPO_TOKEN secret it succeeds with a notice, so the template ships no credentialed service. App Config documents the secret, inputs, credentials and OTA updates. Refs #137 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adding a feature is four manual steps (screen, route file, strings, test) that are easy to get half right. npm run new-feature -- <name> [--route public|signed-in|tab] creates the screen as a named export, the one-line route in the matching group (declaring a tab in the tabs layout), its title string, and a test that opens the route. It checks the name and every target first, so a refused name changes nothing. Refs #138 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adopters in regulated domains need pinning, and getting it wrong (one pin, a leaf key that rotates) locks users out. The recipe pins the API hosts with react-native-ssl-public-key-pinning: backup pins, how to get the hashes, a module that holds the app's HTTP clients until pinning is on and fails closed, a check that it fails closed, key rotation, and the web limitation. The library is pinned in docs/recipes for docs:check. init-project's prompt and docs now speak of "the recipes", which it removes or keeps together. Refs #139 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The i18n seam takes more dictionaries, but nothing showed how to add a language end to end. The recipe adds an Arabic dictionary (partial, with English fallback per key), picks the language from the device with expo-localization, sets the layout direction with I18nManager (and the page's lang and dir on the web), explains when the direction applies and which config plugin options to leave unset, and gives a test that fails on a missing key or a dropped placeholder. init-project now strips the @recipes block in Plug In a Provider, which links the recipe. Refs #140 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Maestro workflows ran only when dispatched, so a change outside the lockfile (runner image, emulator, a download) could break the flows unnoticed between releases. E2E (Android) now also runs weekly in Expo Go, gated on a repository variable: a repository made from the template doesn't have it, so its weekly run is skipped at no cost. A scheduled failure opens or updates an issue from a separate job, the only one that can write issues. No ref input and no new caches (#112). Refs #141 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft for #134: CI runs on the PR. Not to be merged until the maintainer decides (when the store Expo Go supports SDK 58, or at the deadline, about 2026-10-27).
unstable_settings.anchor; back buttons decided when pressed; "Go home" triesreplaceeven whendismissTothrows; strict React Native types (password ref, tab icon colors);web.output: 'single'.UNSAFE_queries; a DocumentTitle stand-in for screens' titles; an asset-registry mock for expo-asset 58.Refs #134
🤖 Generated with Claude Code