You must capture the source parameter first by enclosing the value in parenthesis
RewriteCond &%{QUERY_STRING}& &source=(.*?)&
Now you can use the captured value with %1, see RewriteCond
TestString is a string which can contain the following expanded constructs in addition to plain text:
...
- RewriteCond backreferences: These are backreferences of the form %N (0 <= N <= 9). %1 to %9 provide access to the grouped parts (again, in parentheses) of the pattern, from the last matched RewriteCond in the current set of conditions. %0 provides access to the whole string matched by that pattern.
RewriteRule ^page/$ $0?campaign=%1 [L,R]
Again see the manual RewriteRule
In addition to plain text, the Substitution string can include
- back-references ($N) to the RewriteRule pattern
- back-references (%N) to the last matched RewriteCond pattern
- server-variables as in rule condition test-strings (%{VARNAME})
- mapping-function calls (${mapname:key|default})
And you must not use the flag QSA, because this adds any new query strings instead of replacing the existing one
Using the [QSA] flag causes the query strings to be combined.
Unrelated, but never test with R=301!
source?