@@ -22,12 +22,40 @@ export const config = {
2222} ;
2323
2424export async function middleware ( request : NextRequest ) {
25+ let cookiesToSet : Record < string , string > | undefined = undefined ;
2526 const { pathname } = request . nextUrl ;
2627 const activeAccount = request . cookies . get ( COOKIE_ACTIVE_ACCOUNT ) ?. value ;
2728 const authCookie = activeAccount
2829 ? request . cookies . get ( COOKIE_PREFIX_TOKEN + getAddress ( activeAccount ) )
2930 : null ;
3031
32+ // utm collection
33+ // NOTE: this is not working for pages with rewrites in next.config.js - (framer pages)
34+ // if user is already signed in - don't bother capturing utm params
35+ if ( ! authCookie ) {
36+ const searchParamsEntries = request . nextUrl . searchParams . entries ( ) ;
37+ const utmParams : Map < string , string > = new Map ( ) ;
38+ for ( const param of searchParamsEntries ) {
39+ if ( param [ 0 ] . startsWith ( "utm_" ) ) {
40+ utmParams . set ( param [ 0 ] , param [ 1 ] ) ;
41+ }
42+ }
43+
44+ // if we have utm params, set them as cookies
45+ if ( utmParams . size ) {
46+ for ( const [ key , value ] of utmParams . entries ( ) ) {
47+ // if its already set - don't set it again
48+ if ( ! request . cookies . get ( key ) ) {
49+ if ( ! cookiesToSet ) {
50+ cookiesToSet = { } ;
51+ }
52+
53+ cookiesToSet [ key ] = value ;
54+ }
55+ }
56+ }
57+ }
58+
3159 // logged in paths
3260 if ( isLoginRequired ( pathname ) ) {
3361 // check if the user is logged in (has a valid auth cookie)
@@ -36,12 +64,11 @@ export async function middleware(request: NextRequest) {
3664 const searchParamsString = request . nextUrl . searchParams . toString ( ) ;
3765
3866 // if not logged in, rewrite to login page
39- return redirect (
40- request ,
41- "/login" ,
42- `next=${ encodeURIComponent ( `${ pathname } ${ searchParamsString ? `?${ searchParamsString } ` : "" } ` ) } ` ,
43- false ,
44- ) ;
67+ return redirect ( request , "/login" , {
68+ permanent : false ,
69+ searchParams : `next=${ encodeURIComponent ( `${ pathname } ${ searchParamsString ? `?${ searchParamsString } ` : "" } ` ) } ` ,
70+ cookiesToSet,
71+ } ) ;
4572 }
4673 }
4774
@@ -50,7 +77,15 @@ export async function middleware(request: NextRequest) {
5077
5178 // if it's the homepage and we have an auth cookie, redirect to the dashboard
5279 if ( paths . length === 1 && paths [ 0 ] === "" && authCookie ) {
53- return redirect ( request , "/team" ) ;
80+ return redirect (
81+ request ,
82+ "/team" ,
83+ cookiesToSet
84+ ? {
85+ cookiesToSet,
86+ }
87+ : undefined ,
88+ ) ;
5489 }
5590
5691 // if the first section of the path is a number, check if it's a valid chain_id and re-write it to the slug
@@ -69,6 +104,7 @@ export async function middleware(request: NextRequest) {
69104 return redirect (
70105 request ,
71106 `/${ chainMetadata . slug } /${ paths . slice ( 1 ) . join ( "/" ) } ` ,
107+ cookiesToSet ? { cookiesToSet } : undefined ,
72108 ) ;
73109 }
74110 } catch {
@@ -83,20 +119,18 @@ export async function middleware(request: NextRequest) {
83119 // special case for "deployer.thirdweb.eth"
84120 // we want to always redirect this to "thirdweb.eth/..."
85121 if ( paths [ 0 ] === "deployer.thirdweb.eth" ) {
86- return redirect (
87- request ,
88- `/thirdweb.eth/${ paths . slice ( 1 ) . join ( "/" ) } ` ,
89- undefined ,
90- true ,
91- ) ;
122+ return redirect ( request , `/thirdweb.eth/${ paths . slice ( 1 ) . join ( "/" ) } ` , {
123+ permanent : true ,
124+ cookiesToSet,
125+ } ) ;
92126 }
93127 // if we have exactly 1 path part, we're in the <address> case -> profile page
94128 if ( paths . length === 1 ) {
95- return rewrite ( request , `/profile${ pathname } ` ) ;
129+ return rewrite ( request , `/profile${ pathname } ` , cookiesToSet ) ;
96130 }
97131 // if we have more than 1 path part, we're in the <address>/<slug> case -> publish page
98132 if ( paths . length > 1 ) {
99- return rewrite ( request , `/published-contract${ pathname } ` ) ;
133+ return rewrite ( request , `/published-contract${ pathname } ` , cookiesToSet ) ;
100134 }
101135 }
102136
@@ -108,15 +142,22 @@ export async function middleware(request: NextRequest) {
108142 if ( firstTeam ) {
109143 const modifiedPaths = [ ...paths ] ;
110144 modifiedPaths [ 1 ] = firstTeam . slug ;
111- return redirect (
112- request ,
113- `/${ modifiedPaths . join ( "/" ) } ` ,
114- request . nextUrl . searchParams . toString ( ) ,
115- ) ;
145+ return redirect ( request , `/${ modifiedPaths . join ( "/" ) } ` , {
146+ searchParams : request . nextUrl . searchParams . toString ( ) ,
147+ cookiesToSet,
148+ } ) ;
116149 }
117150 }
118151 // END /<address>/... case
119152 // all other cases are handled by the file system router so we just fall through
153+ if ( cookiesToSet ) {
154+ const defaultResponse = NextResponse . next ( ) ;
155+ for ( const entry of Object . entries ( cookiesToSet ) ) {
156+ defaultResponse . cookies . set ( entry [ 0 ] , entry [ 1 ] ) ;
157+ }
158+
159+ return defaultResponse ;
160+ }
120161}
121162
122163function isPossibleEVMAddress ( address : string ) {
@@ -125,20 +166,46 @@ function isPossibleEVMAddress(address: string) {
125166
126167// utils for rewriting and redirecting with relative paths
127168
128- function rewrite ( request : NextRequest , relativePath : string ) {
169+ function rewrite (
170+ request : NextRequest ,
171+ relativePath : string ,
172+ cookiesToSet : Record < string , string > | undefined ,
173+ ) {
129174 const url = request . nextUrl . clone ( ) ;
130175 url . pathname = relativePath ;
131- return NextResponse . rewrite ( url ) ;
176+ const res = NextResponse . rewrite ( url ) ;
177+
178+ if ( cookiesToSet ) {
179+ for ( const entry of Object . entries ( cookiesToSet ) ) {
180+ res . cookies . set ( entry [ 0 ] , entry [ 1 ] ) ;
181+ }
182+ }
183+
184+ return res ;
132185}
133186
134187function redirect (
135188 request : NextRequest ,
136189 relativePath : string ,
137- searchParams ?: string ,
138- permanent = false ,
190+ options :
191+ | {
192+ searchParams ?: string ;
193+ permanent ?: boolean ;
194+ cookiesToSet ?: Record < string , string > | undefined ;
195+ }
196+ | undefined ,
139197) {
198+ const permanent = options ?. permanent ?? false ;
140199 const url = request . nextUrl . clone ( ) ;
141200 url . pathname = relativePath ;
142- url . search = searchParams ? `?${ searchParams } ` : "" ;
143- return NextResponse . redirect ( url , permanent ? 308 : undefined ) ;
201+ url . search = options ?. searchParams ? `?${ options . searchParams } ` : "" ;
202+ const res = NextResponse . redirect ( url , permanent ? 308 : undefined ) ;
203+
204+ if ( options ?. cookiesToSet ) {
205+ for ( const entry of Object . entries ( options . cookiesToSet ) ) {
206+ res . cookies . set ( entry [ 0 ] , entry [ 1 ] ) ;
207+ }
208+ }
209+
210+ return res ;
144211}
0 commit comments