define replaces identifiers in source with the literal text of the configured value before parsing continues. A value must therefore be the source code of the expression, not the value itself. Writing define: { __API__: 'https://example.com' } substitutes a bare, unquoted URL and yields a syntax error or a reference error in the output.
The correct form wraps the value: JSON.stringify('https://example.com'). This trips people most often when values come from process.env, where the type is already a string and looks like it should just work.
Because the replacement is textual and unscoped, a short identifier can be replaced inside unrelated code, including in strings in some configurations. Prefer import.meta.env with a VITE_ prefixed variable for anything that is really configuration, and reserve define for build-time constants and for replacing globals that a dependency expects, such as shimming global to globalThis for a browser build.