As always: It depends.
- Old skool Auth Code = Store token on server side
- Auth Code + PKCE Public Client = Store at client side
Auth Code as described in RFC6749 (old skool)
Don't use this client side, use Auth Code + PKCE instead.
The Authorization Grant flow as described in RFC6749 (https://datatracker.ietf.org/doc/html/rfc6749). In this "flow", the client sends a request for a code to the authorization server, the server responds with a code, the client exchanges the code for a token. (Don't use this on the client side, use server side only)
Lately, this is the preferred solution for web apps. The trend is to create a confidential client and have the code <> token exchange take place on the server side. (https://datatracker.ietf.org/doc/html/rfc6749#section-2.3). That way, only the computers that have been entrusted the client_secret are able to obtain a token.
Auth Code requires storing the access token on the server side.
(Note: this flow is also used for mobile apps, but that's a topic on it's own...)
Auth Code + PKCE (Public Client) as described in RFC7636
The second type of "flow" is the Authorization Code with PKCE (Public Client) as described in RFC 7636 (https://datatracker.ietf.org/doc/html/rfc7636). This flow is designed to use on the client side. In this scenario, the client generates a password (a.k.a. code verifier) and includes that in the request for a code to the authorization server. The server responds with a code, the client exchanges the code+the password for a token.
In case of "flow #2", the public client, there's one important risk to consider. In case of Code + PKCE Public Client, there are no constraint to which computer may initiate the authentication request or receive the token. That means that if an attacker could have means to obtain the code verifier and the code, and if the attacker succeeds, the attacker is able to exchange it for a token. If this is an acceptable risk to you, or if this risk is mitigated, feel free to store the token in the SPA with the considerations that Gabor mentioned
Hope this helps?