Tumgik
#f12 by the way; that's how you get a lot of stuff
medicinemane · 9 months
Text
Ok, wasn't my fault I opened that window
The image came from from piece of shit website that won't let you right click here, and won't let you right click on the site (which has a fucking overlay here and basically funnels you to that site)
Well fuck you, I downloaded it anyway. You added more work to it, but that just made me more determined. Bird photo is mine now
#sorry; I just feel strongly that I'm allowed to store pretty much anything I encounter on the internet on to my computer#not allowed to use it for anything; it's not like I own the creation of it; but I get to make a back up#for one thing that's how I remember and find artists and stuff again down the road#see a picture and reverse image search to track down who it was from#but nah... I get to copy anything; maybe that sounds entitled but like... this shit ain't fungible and it cost nothing for me to copy it#I'm not reposting; I'm not doing shit with it other than keeping it for myself#and frankly... this is just how the internet works; people save shit all the time#this bird photo isn't special just because some company thinks they're hot shit#if I can download from youtube I can download from you#occasionally I get stymied on how to download a video from some place... but it's rare; and it makes me hate the site#it's just if push comes to shove and we're blunt about it I'm super pro piracy#pro creatives getting supported and whatnot; but pro access to all information; and that shitty site ain't a creative#f12 by the way; that's how you get a lot of stuff#select either image; or more often media and reload the page#then... scout for what you want; open it in a new tab; and if you manage that you can always download it#it's only when they hide it better than that where you can't make it happen#but if you find it in f12 it's yours; that's just the raw file#all they did was try to obscure where it was
1 note · View note
auxiliarydetective · 9 months
Text
Technically Evie's Ask Extravaganza, The Finale - Allow me to introduce to you...
Evie's Multiverse - The Official™ Prompt List
Rules:
Send me an ask with the characters and prompts you want
Combining prompts is allowed, including across categories
You don't have to ask for a character and their S/O but lots of these prompts are best suited to write OTPs - use your best judgement to assess whether your prompt is such a prompt
Include any special preferences or details you'd like to see - this also means that you should include the level of smuttiness you want to see if the prompt you sent me could be interpreted in a spicy way
Be nice
What I will write:
Stories for my OCs and their ships, any day, anytime if I have any time and energy to spare
Ships between canon characters - if I know the characters and their dynamics, I can definitely try. If I actively ship them, I definitely will try
AUs, just specify it in your ask
Spicy stuff, including some kinks BUT refer to the rest of the rules
Heavy topics
What I will NOT write:
Explicit smut. I just don’t feel comfortable doing it. Fade-to-black? Yes. But no smut. Trust me, there are other writers who do a better job and you yourself have an imagination ;) Not as much of a rule anymore by now but it might take a while for me to do it. Also, it won't be the sort of smut you're used to but rather the way I write smut, which includes allusions, metaphors and euphemisms and excludes your typical smut words as much as possible - if you don't like that style quirk of mine, don't request smut.
Incest and pedophilia
Most pregnancy stuff
As a general rule of thumb, if you don’t know whether I would be willing to write something, just ask. I've intentionally left some of these rules more or less vague to give the space for interaction. If I find something in your ask that I don't want to write that way, I'll let you know and maybe modify the prompt a little if possible so I can still write something for you without having to fully turn you down. Either way, communication is key!
You can avoid the spicy prompts on this list by just not scrolling down all the way. They're the last block of text. :)
Fluff
☆ F01: Accidentally falling asleep together
☆ F02: Adjusting the other's necklace/tie
☆ F03: Caught in the rain
☆ F04: Compliments
☆ F05: Cooking as a love language
☆ F06: Cuddles
☆ F07: Described through the eyes of their lover
☆ F08: Falling asleep in the other's lap
☆ F09: Head pats/playing with the other's hair
☆ F10: Humming/singing
☆ F11: Needy for attention
☆ F12: Pet names
☆ F13: Puppy dog eyes
☆ F14: Reading together
☆ F15: Sharing food
☆ F16: Sitting on the other's lap
☆ F17: Slow dancing
☆ F18: Sticking warm/cold hands beneath the other's shirt
☆ F19: "Wait, you think I'm cute/pretty/...?"
☆ F20: "You look beautiful."
☆ F21: "You smell nice."
☆ F22: "You’re an idiot." "But I'm your idiot."
Kiss Prompts
♡ K01: A kiss as an apology
♡ K02: A kiss on the hand
♡ K03: An unexpected kiss
♡ K04: Cheek kiss
♡ K05: Desperate kiss
♡ K06: Forehead kiss
♡ K07: Kiss goodbye
♡ K08: Kissing the tears away
♡ K09: Passionate kisses that leave them breathless
♡ K10: Neck kisses
♡ K11: Sleepy morning kisses
♡ K12: Staring at the other's lips, trying not to kiss them
♡ K13: Wandering kisses
♡ K14: "Kiss me."
♡ K15: "Your lips are so soft...
Whump/Hurt & Comfort
♧ W01: Caring for the other while sick
♧ W02: Finding the other crying
♧ W03: Insecurities
♧ W04: Kidnapped
♧ W05: Nightmare
♧ W06: Patching up a wound
♧ W07: Poison
♧ W08: "Can you talk?"
♧ W09: "Don’t move."
♧ W10: "How many fingers?"
♧ W11: "I can't feel my legs."
♧ W12: "I can't get up."
♧ W13: "I'm fine."
♧ W14: "Is that blood?"
♧ W15: "Please, don’t leave."
♧ W16: "Wake up, damn it, wake up!"
♧ W17: "You’re safe with me."
♧ W18: "You’re doing great."
Tropes
◇ T01: Domestic
◇ T02: Drunken confession
◇ T03: Forced Proximity
◇ T04: "Oh. Oh."
◇ T05: Secret relationship
◇ T06: Sharing body heat
◇ T07: Song fic - Pick a song from their OC or ship playlist and I'll use it as a prompt
◇ T08: Soulmates AU
◇ T09: There was only one bed
◇ T10: "Who did this to you?"
◇ T11: Wild card - you decide what I write!
Spicy
♤ S01: Body worship
♤ S02: Pinned
♤ S03: Roaming hands
♤ S04: Touch-starved
♤ S05: "Do you really want to do this?"
♤ S06: "Don’t tease me like that."
♤ S07: "I won’t bite - unless you want me to."
♤ S08: "I'll be very gentle."
♤ S09: "Make me."
♤ S10: "Say that again."
♤ S11: "Tell me how much you want me."
♤ S12: "Touch me."
4 notes · View notes
After Your Love | Sam Winchester
✦ pairing — Sam Winchester x gender neutral!Plus Size Reader
✦ word count — 1k
✦ summary — Sam and you come to a silent understanding.
✦ request — Could I request a canon universe Sam Winchester, with F12, F14, F49, and F50?
✶ F12 - “I love you more than coffee.” distant gasps
✶ F14 - “I’m tired and my bed feels so empty without you here.”
✶ F49 - “That night you kissed me and I thought I might melt.”
✶ F50 - “From the moment I saw you, I knew I was in love.”
✦ warnings — light angst, mentions of alcohol, fluff.
════════════════════════
You were dreading the moment you would reach your street. Tiredness wasn’t enough yet to motivate you to arrive at an empty home.
Ironically, it really was your home and you would never dare to say you didn’t consider it as such.
Well-lit streets weren’t a norm around your block. You were extremely lucky that yours was the exception. Perhaps it had to do with the fact that there were a lot of children around.
Children made you feel less lonely when they ran across the street, laughing and squealing. You didn’t get to watch them or hear them often, only on the weekends, and even then your work kept its grip on you.
The place welcomed you in all of its coldness. The day had been nice, not too hot but not too cold, yet the living room was freezing.
It was in moments like this that you missed your small one-bedroom apartment. It didn’t feel lonely even though you were always by yourself.
This wasn’t that different, you still lived on your own. But Sam visited often, there was no better way to spend alone time than at your place.
Everywhere you looked at, a piece of him reigned. A stack of books, his favorite mug, that warm jacket...
You missed him. Something you were also used to. You would never complain about his line of work, he had been honest to you about it even before dating. You just missed him when he was out of town, plain and simple.
Sam put a lot of effort into the relationship, you felt comfortable with him because of that.
He would call soon, he always did. So in the meantime, you took a shower and got ready for bed.
You were barely finished with your nightly routine when your cellphone rang. Sam’s photograph lit up the screen.
Giddy, you accepted the call and greeted him, “Hi.”
“Hey, you.” He sounded tired.
“How’s it going?”
He sighed heavily. “It’s going.”
You made a face. That meant he would take longer than usual.
“How was your day?”
“Long,” you admitted. “The weekend will be a nightmare.” You got under the covers as you continued speaking, “I think I’ll visit my mom on Sunday after work.”
Sam sounded like he liked the idea as he said, “Say hi to her from me. And have fun with her.”
“I’ll try.”
His excitement faded. “What’s wrong?”
Inwardly cursing yourself for letting him know how you were feeling without even saying it, you shuffled on the bed. “I’m tired and my bed feels so empty without you here.”
He huffed a small and sad laugh. “I know, babe. I miss you too.”
“You’ll make it up to me.” Or at least you hoped.
“I will, but I gotta go now. I just wanted to make sure you were doing all right.”
“It’s okay,” you assured him, trying your hardest to hide your disappointment. “Be safe. I love you.”
“I love you more than coffee.”
You heard Dean distantly gasp in the background before the line clicked.
════════════════════════
It was raining, therefore children were out with their parents, having fun with the puddles. Their glee, while endearing, wasn’t the reason why you were at peace. Not entirely.
You finally felt safe. After almost two excruciatingly long weeks without him, you had him back.
A free day, rain, hot coffee, a movie, and Sam. What else could you need?
The bliss of being in Sam’s arms could never be compared. He had a natural warmth to it that had little to nothing to do with his body.
You were sat with your back against his chest, with your hands on top of his as his breath tickled your skin.
“Wanna know something?” The question vibrated around the room, mixed with the tapping of the rain on the ceiling.
“Anything.” You would never deny him. Sam’s opinions were treasured by you, just like his random comments and his bad jokes.
“From the moment I saw you, I knew I was in love.” He let out a small laugh. “I sound like a teenager, but it’s true.”
You smiled, leaning the side of your head against his shoulder. “Yeah?”
He hummed. “Remember when we celebrated Dean’s birthday next town?” It was your time to hum. “That night you kissed me and I thought I might melt.”
“I’m surprised you remember that. You were so drunk...”
Alcohol had helped you to get bold that night, and although at the moment the tiniest part of your brain told you you would regret it, by the next morning you were happy you had gone for it.
But Sam had been in a worse state than you. He had told you it was okay to kiss him, but he hadn’t really acknowledged that night when he officially asked you out.
“How could I forget?”
“Drunk me tends to forget some stuff,” you playfully teased him, giving him a light kiss on the jaw.
Sam tightened his grip around you, forcing you to shift so you wouldn’t hurt your neck.
“You know I love you, right?”
“I’ve never felt so loved before.” As though he had realized something, he added, “Not romantically, at least.”
“I’m glad,” you whispered, wrapping your arms around his shoulders. It was an odd position, but you didn’t really care. “I have lots of love to give you still.”
“You better,” he said breathily, “I don’t want to know how life would be after your love.”
“Oh, Sam,” you sighed. He was more romantic than you, definitely. And you only loved him more for it. “I don’t want you to know that either.”
You couldn’t promise things would be perfect or that you would make it until the end, but you were aware that Sam knew that so you discarded the idea of ruining the moment stating the obvious.
So instead you peppered his profile with kisses and relaxed against his warmth, feeling him relax as you came to a silent understanding.
70 notes · View notes
vonkarma2 · 3 years
Note
E8, F12, and L1 for angel?
What’s one of your OC’s biggest regrets?
In his backstory probably being really passive for most of his life, like not telling anyone his situation or later on not going out into the world or trying to get a job or anything. During the story he ditched one of his friends and that friend ended up getting killed so he wishes he was at least there whether or not he could have done anything
Would they enjoy a theme park?
I want to answer this in a way that says something deeper about his character but I can’t think of anything. he would like it though he has a lot of energy and there’s a lot of stuff to do so he’d want to try everything and probably enjoy it a lot
What are their favorite kinds of flavors– Sweet, salty, sour, spicy, creamy, et cetera?
I accidentally answered this instead of L1 but whatever I’ll keep it. Salty + umami he also really likes seafood so whatever that flavor is called
How have your characters changed since you created them?
For Angel in particular I think his personality hasn’t changed much outside of sucking less, originally he was pretty much the same person, maybe slightly worse? When I first came up with the concept for him (he was actually the first character I thought of in this universe) he was more like medieval and fairy tale ish design wise, and he was in his late 20s instead of being 19. For a while I had him be married, like in a political arranged marriage, I thought it was funny but it was such a terrible idea
2 notes · View notes
rockshortage · 4 years
Note
*Cracks knuckles* Ow. Let's see, how about: A6, 16. B1, 12. C1, 2, 3, 5, 8. D4. E2, 3, 7. F2, 5, 10, 12 (Sorry, but also not sorry) I6. L1, 2, 4, and 9 :)
hoo boy that took a while
A6) Does your OC tend to assume their interpretation of events and reality is correct, or do they question it? I.e., “I’m sure that’s what you said” versus “It’s possible I misheard you.”
Ah, he questions himself a lot. Maybe he wasn’t listening well enough because he was too distracted by being anxious? Maybe he misinterpreted this event, because his background knowledge on it was lacking, he doesn’t know the full story and opinions from all sides, he’s not sure he can form a well educated opinion on this--
A16) Does your OC have to go through their own trials to learn a lesson, or do they listen and learn from observation and lecture? I.e., does your OC listen when someone tries to tell them the importance of budgeting, or do they have to go experience what happens if you don’t budget first?
Hector needs to do it himself for Science, because how else is he to truly know, if not from his own personal experience? Trusting what people tell you is good and all but gathering data yourself is better.
Unless we’re talking about raider politics, in which case there’s not really a good way for Hector to gather data without seriously endangering him and friends, so he’ll just listen to Gage.
B1) Do they believe you have to give respect to get it, or get respect to give it?
Generally, he believes it’s necessary to give people respect before you can expect it in return. He learns that many people do not in fact think the same way. He’ll still want to extend basic courtesy to them even if they’re assholes, unless they disrespect/piss him off to the extremes, or if their actions threaten his position and in turn the well-being of himself and friends.
B12) Your OC orders something to eat and gets their order done in a pretty wrong way, something they can’t just pick off or whatnot to correct, or something major is missing. What do they do?
Have a back and forth about it in his head – ah it’s not so bad it’s still fine, but then again he really wanted it differently… but he doesn’t wanna bother them and be entitled about it, but man… :( Might get close to pointing it out but chances are slim that he’ll actually get someone to correct the order. It’ll be disappointing but he’ll eat it.  
C1) Does your OC have a moral code? If not, how do they base their actions? If so, where does it come from, and how seriously do they take it?
Eeeh, not a super strong one. His baseline are general societal morals and norms, like… help person good, kill person bad. Most of the time he’ll base his actions on what feels right for him and for his friends. He’ll consider: will doing this make me feel bad afterwards? Will it have a negative impact on other people, who don’t deserve it? Is that consequence worth it because it saves my own skin or helps/protects my friends?
C2) Would your OC feel bad if they acted against their morals? If not, would they find a way to excuse themselves for it?
Bringing back the point about sacrificing for the greater good. He’d consider that the morally right thing to do because it impacts fewer people negatively. But making that sacrifice endangers his friends, whose lives for him personally are worth much more than an abstract crowd of people. So he chooses to not do the thing for the greater good and save his friends instead, and yes, he would feel very bad on the one hand, because oh boy. As far as most people are concerned, he did a horrible terrible thing and was extremely selfish and absolutely chose wrong. But on the plus side, and that’s a very big huge plus- he still has his friends. And still having his friends makes him feel less bad than how he would have felt if he didn’t have his friends anymore.
So uh… yes and no.
C3) Is it important for them to be with people (socially, intimately, whatever) whose major ideological tenets align with their own?
More or less. He can’t hang out well with people he completely disagrees with in every way, of course that’s not going to work. But Hector is… how to say… kinda boring when it comes to ideals and opinions and all that stuff. He just doesn’t have very strong ones in general. Which can make him a little bland and potentially spineless, but also pretty agreeable. As long as they don’t constantly shove their great big opinions in his face, they’ll get along well enough.
C5) Do your OC’s morals and rules of common decency go out the window when it comes to those they don’t like, or when it’s inconvenient? Aka, are their morals situational?
I think I kind of answered this in C2. Basic morals do get thrown out the window if friends are threatened, or if he gets pissed off enough. He’d have to be really pissed off though. As well as being post having-grown-a-spine(-at-least-partially). Hurting people bad but being insufferable to Hector also bad so guess what fucker
C8) Is your OC more practical or ideal morally? I.e., do they hold people to high expectations of behavior even if it’s not realistic for the situation, or do they have a more realistic approach and adapt their morality to be more practical?
Again a little tricky because I’m having trouble coming up with a scenario that would help me make up my mind with a definite answer. I’m leaning more towards a practical approach 1) because Hector is more of a realist/pessimist in general, 2) he doesn’t want to like… be overly demanding
D4) Would they like to be immortal? Why, why not? If they are immortal, would they rather not be?
The more he thinks about it the more meaningless life seems to get for someone like him. Solution: don’t think about it! Repress that shit because it’s not like you can do anything about it anyway. Also an involuntary solution but one that helps nonetheless: have shit memory so that you don’t feel like you’ve lived too many lifetimes.
If you were to ask him, the answer you get completely depends on the headspace he’s in at the moment. If he’s just vibing, going about his day and things are going well then yeah! Immortality isn’t so bad. If you catch him on an off day, things aren’t going so well, maybe he just thought about having to deal with losing his friends eventually… then you obviously get the opposite answer.
E2) Which of the nine types of intelligence is your OC strongest in? Weakest? (Linguistic, existential, naturalist, et cetera)
I know I talked about this before and I grouped them from strong to medium to weak but I can’t for the life of me find the post anymore (thanks tumblr for your useless garbage search and tagging features). So I can’t even check if I’m still on the same wavelength with past me :v
From strongest to weakest we have…
Logical-mathematical
Spatial
Linguistic
Bodily-kinesthetic
Musical
Naturalist
Interpersonal
Existential
Intrapersonal
E3) How many languages do they speak?
Three… and a half.
The half language being Swiss German, because I don’t know what the fuck it is even after graduating from language uni
The others: Standard German, English, and French, from strongest to weakest.
E7) Are they a good note-taker? Are they a good test-taker? Do exams make them nervous?
Yes, yes, and yes. He’s very good at taking notes considering most of science is documentation. And even now when he’s not doing a lot of Formal Science things, he still writes in his journal almost daily, summing up events and making notes of important things. He gets nervous with tests with all the self doubt if he really prepared well enough and the unpredictability of the questions that will be asked, but once the pen is in his hand, he just blazes through it.
F2) What’s their ideal home look like? Where is it?
Someplace underground, safe and sturdy like a vault. Industrial aesthetic is welcome and he wants to have plenty of space, but it shouldn’t feel huge and empty. Needs to be homey, even if it might feel a little rustic to the average person. Having it built into a mountain would be sick, so he still has the perfect protection from the sun, but he doesn’t have to crawl out of a hole in the ground like some kind of worm – instead he opens the door and gets the most amazing view immediately.
… and I promise, only after writing the above did I remember that he pretty much lives in a mountain already, just a plastic one. Close enough.
F5) How handy are they? Can they fix appliances, cars, cabinets, et cetera?
Quite handy indeed. He can fix most things, he usually just needs some time to (re-)familiarize himself with the object and its functions. A lot of it also involves trial and error, but he’ll figure it out eventually.
F10) Do they engage in any of the arts? How good do you intend them to be? Would they agree they are?
He’d actually be really good at pen/pencil drawing, what with making technical illustrations and blueprints of Science Stuff, but it’s not a skill that’s applied in an artsy setting. When the goal is to draw for the sake of drawing, evoking emotion, or paint with a brush, that’s probably when shit would fall apart. I can’t remember who the artist was, but it reminds me of this little comic about Paladin Danse – in which he’s extremely good at technical drawings but then he attempts to draw a dog and it just looks…wrong.
Now with music, he’s more likely to engage in it in an artful way. He likes to sing, even if he very rarely does it now that he has people around him more often than not. Before, he’d just be alone in his lonely place and sing and scream to his heart’s content, but now he’s too awkward to do it, because someone might hear him. He is pretty good at it though, considering how much alone time he’s had to practice.
F12) Would they enjoy a theme park?
The rides and junk food? Yes absolutely. But the giant crowd and every little consequence it entails, nope, no thank you, he’ll just leave it be.
You bet he’s gonna go on the rides at nuka world though once they got them back up and working, because the crowd isn’t as big as pre-war and he’s the fucking overboss and can skip lines and restrict access to others however he damn pleases.
I6) Could they eat the same thing they enjoy over and over and not get bored of it quickly?
He can, but that doesn’t mean he enjoys it. The first month or so at nuka world he almost exclusively lives off of some shitty nutrient bars. In some scenarios, food just exists as sustenance and not as something to be enjoyed.
In a preferable scenario though, it is to be enjoyed. And I think while he would get bored of it after a while, it’d take longer than for the average person. And even then, he’s just happy he can eat something enjoyable at whatever pace he likes instead of having to scarf down Compressed Nutrient
L1) How have your characters changed since you created them?
He stopped existing in a void, which is a pretty damn big change. Now he has a whole world and other characters to interact with, that contribute to shaping and developing his personality.
L2) What do you consider the biggest themes in your character, if any?
Oof, this is hard. Maybe… getting to know yourself? Accepting change, personal growth?
L4) Would you hang out with your OC if you could?
I’m actually not sure sjdfsdnsv
Like yes he is sweet bean who must be protected, but that doesn’t change the fact that he is a weird little old man. I guess if we can just chill listening to music and he can go off about crustaceans or something and we speak The Horrible Language, why the fuck not
L9) How did you come up with your OC?
Masks cool. Me especially like gas masks. Unhinged science characters also cool. Make generic but still sliiiightly unique design and make it a point to not have him be a young pretty boy character despite having immortality. Add lots of weaknesses to compensate for the immortality. Add science personality things and complete the picture with projections of my own personality. Boom, you’ve got yourself the beginnings of a Hector
3 notes · View notes
whit3zzz · 5 years
Text
Something Awesome Natas 11
This is a very long posting because the challenge is actually a little logically challenging. I spent a day going over my logic for this before realising I just forgot to do a base64 encode tho, so maybe I’m molto retardio.
I also recommend that it’s done on #ffffff because the key is dynamic based on the input (changing the colour changes the cookie, and the key is dependant on the colour).
First things first, we should follow the clue: Cookies are protected by XOR encryption. Because of the properties of the XOR function, this means 3 things:
1) DATA ^ KEY == ENCRYPTED 2) DATA ^ ENCRYPTED == KEY 3) ENCRYPTED ^ KEY == DATA
where ^ == `XOR` and order of operation is unimportant.
Now that we know this is a cookie challenge, let’s F12 on chrome and check the cookies. Observe that there’s an extra one compared to other challenges.
Tumblr media
After storing the data value in python, we also need to sanitise it by recognising that %3D is the percent equivalent of “ = ” (which is used as a padding to reach a multiple of 4 for any encoding/decoding which require mod 4).
Now let’s take a look at the source code.
Tumblr media
OK, that’s actually a lot of reading. However, let’s try and break it down. 
The function loadData takes the cookie and performs:
$tempdata = json_decode(xor_encrypt(base64_decode($_COOKIE["data"])), true);
After performing a series of checks to make sure you haven’t done anything the challenge doesn’t want you to do, it then passes it onto $mydata which is later passed to the loadData function used to dynamically display html. Note that $defaultdata at the very top sets “showpassword” to “no” meaning that before we pass our fake cookie back in, we need to set that to “true” or “yes”.
So did you catch all that? If not, here’s a simpler explanation:
1) $defaultdata is set to not show passwords. 2) $defaultdata is passed into $loadData, which uses it as a base and stores it into $myData 3) If $tempdata exists, it’s used instead ($tempdata is the info from the cookie) and put into $mydata 4) $loadData then calls $mydata, which theoretically doesn’t show passwords
So how do we exploit this? Well, we need to set the cookie that $tempdata decodes to have the field “showpassword” as “yes”.
With that in mind, let’s now construct a plausible way for that to occur.
1) Obtain DATA 2) Obtain ENCRYPTED 3) Perform DATA ^ ENCRYPTED to obtain KEY 4) Modify DATA so “showpassword” is now true 5) Perform KEY ^ NEW_DATA to obtain NEW_ENCRYPTED 6) Chuck that shit into the cookie field and refresh the page Y E E T
We already have ENCRYPTED so that’s step (2) done, but where do we find DATA for step (1)? Well, by looking at the code, we see that it’s simply defaultdata (it’s being passed into the loadData function on the line where $data = loadData($defaultdata) )
Fortunately for us, we can now perform DATA ^ ENCRYPTED for step (3). We need to get rid of the json and base64 encoding so by applying base64 for the RHS and json to the LHS, we get the code:
Tumblr media
To be fair, I should’ve used chr() on the line print(string) because the output was
Tumblr media
 but I just chucked it into google and it gave me qw8Jqw8J....   which is the key!
(ignore the 44 by the way, that was a debug statement)
So now we have the key, let’s move onto step (4). That’s easy enough: 
Tumblr media
Step (5) now demands that we basically reverse the steps of the code above. So by swapping around some stuff so now we XOR before we base64, we get the code:
Tumblr media
And the output:
Tumblr media
Which is the encrypted base64′ed, XOR’ed and JSON’ed thing that goes into the cookie field ready for step (6).
Tumblr media
Now we just copy that into the cookie field and refresh! And that’s challenge 11!
1 note · View note
llampacaeatingguppy · 6 years
Note
WAIT DID I FORGET TO SEND THE ASK TO YOU? OKAY UH *takes a deep breath* this is a lot. you ready? for jasper and friday (if you so wish it) A2, A22, B2, C8, D4, D5, E3, F5, F12, G4, H7, and L5! i wish you the best of luck on that aahahahahahaha
Ask away, a lot is 100% okay! Sorry it took me a little while to get around to this. I wanted to answer on my computer so that I can actually respond something similar to properly haha
This got long so I’ll pop it under a read more :)
For Jasper:
A2: What alignment are they? Chaotic neutral, lawful evil, et cetera…
Neutral/chaotic good
A22: Is your OC intended to be found generally attractive? Unattractive? Average? Is there a reason why?
Eh, if you’re into the tall, lanky type, I guess he’s pretty good-looking, but he looks pretty average and dorky to me.
B2: Do they get frustrated when lines at places like pharmacies, check-outs, delis, banks, et cetera, are moving slowly?
Not usually. He worked in retail, he’s been there. If he is frustrated, it’s probably at someone being rude and not the workers themselves
C8: Is your OC more practical or ideal morally? I.e., do they hold people to high expectations of behavior even if it’s not realistic for the situation, or do they have a more realistic approach and adapt their morality to be more practical?
It’s a mix, but I’d say he leans more towards realistic
D4: Would they like to be immortal? Why, why not? If they are immortal, would they rather not be?
No. Jasper latches onto people like glue and it’s really hard for him to lose them, so immortality wouldn’t appeal to him that much
D5: Do they believe in ghosts? If not, why? If so, do they think they’re magical/tie into their religion, or are they scientifically plausible?
YES. He doesn’t know how or why, but he’s fully convinced that there’s some terrifying supernatural stuff in the world and will be a huge baby about it if he thinks he’s in danger on encountering it
E3: How many languages do they speak?
Well? One. He took Spanish in high school, but it just didn’t stick
F5: How handy are they? Can they fix appliances, cars, cabinets, et cetera?
Well, he CAN fix things, technically, but he’s not handy. Instead of looking at the broken thing, figuring out what’s wrong, and taking measures to correct it, he just notices it’s broken and charms it so it does what it’s supposed to again
F12: Would they enjoy a theme park?
ABSOLUTELY
G4: What kind of childhood did your OC have?
He has fond memories of most of it. He was sick for part of his childhood before getting diagnosed with celiac disease, and then needing gluten free stuff in the time before the Gluten Free Fad™ somewhat isolated him from other kids. So, the kid’s social life at school was in the toilet for a while, essentially. But outside of that, his dads tried really hard to make sure that his home life was good, and he spent a lot of time on his aunt’s farm playing with Emily, and he had Shawn, the homeschooled kid with odd parents who was at Jasper’s house so often he might as well have been a second child to his dads. He loves that part of his childhood, and it’s the part he remembers more, anyways.
H7: What do they look for in partners? (Emotionally, mentally, physically..)
Food. Not making food, he can do that himself, but being nice about his food. Actually knowing (or at least trying to) what he can and can’t eat and being understanding about it is a huge deal for him. He also thrives on emotional warmth and support and physical affection. As for purely physical attraction, he has two types: “small and delicate” and “looks like they could snap him in half like a twig”
Friday:
A2: What alignment are they? Chaotic neutral, lawful evil, et cetera…
True neutral
A22: Is your OC intended to be found generally attractive? Unattractive? Average? Is there a reason why?
She’s cute. I’ve always designed her to look beautiful in a soft sort of way. It just makes the demon hound transition more fun 
B2:  Do they get frustrated when lines at places like pharmacies, check-outs, delis, banks, et cetera, are moving slowly?
Yeah. Like she won’t be rude about it or anything, but it does frustrate her sometimes
C8: Is your OC more practical or ideal morally? I.e., do they hold people to high expectations of behavior even if it’s not realistic for the situation, or do they have a more realistic approach and adapt their morality to be more practical?
100% idealist. She doesn’t believe in lowering her expectations just so that she can be less disappointed. That doesn’t mean that her expectations are always outrageous, but good luck trying to get her to lower them
D4: Would they like to be immortal? Why, why not? If they are immortal, would they rather not be?
She would at least consider it. I’m not actually sure what her final decision would be, but she would definitely be interested
D5: Do they believe in ghosts? If not, why? If so, do they think they’re magical/tie into their religion, or are they scientifically plausible?
No. Her mom can literally telepathically control corpses, if anyone was going to anger a bunch of ghosts and get a serious haunting problem, it would be her, and she’s been fine for this long.
E3:  How many languages do they speak?
English, Spanish, and passable Polish
F5:  How handy are they? Can they fix appliances, cars, cabinets, et cetera?
It depends on what it is. She can fix up most things that don’t really have that many moving parts (think remodeling type of work), but if the toaster breaks or something? Nope.
F12:  Would they enjoy a theme park?
Yep. She goes to them fairly frequently
G4:  What kind of childhood did your OC have?
Out of touch with a lot of the normal world and constantly in the public eye. Her mother was/is a very controversial figure, and while she actually did try to keep Friday out of that as much as she could, she still grew up learning to always be careful about what she said and did
H7:  What do they look for in partners? (Emotionally, mentally, physically..)
Physically, Friday tends to prefer people on the shorter side, because she worries that somebody too tall would have a clear view down her shirts and the demisexual in her is incredibly uncomfortable with that idea. Outside of that, she values patience and how comfortable she feels being around them
L5: Which OC do you think is the most decent morally or behaviorally?  AKA, which is supposed to a “good guy”?
Oof, that’s hard. Between the two of them, I would say that Jasper might be a better person than Friday just because she can be very… lacking in empathy in certain situations
3 notes · View notes
suzanneshannon · 3 years
Text
How to detect if the User's OS prefers dark mode and change your site with CSS and JS
Tumblr media
I got a tweet from Stevö John who said he found my existing light theme for my blog to be jarring as he lives in Dark Mode. I had never really thought about it before, but once he said it, it was obvious. Not only should I support dark mode, but I should detect the user's preference and switch seamlessly. I should also support changing modes if the browser or OS changes as well. Stevö was kind enough to send some sample CSS and a few links so I started to explore the topic.
There's a few things here to consider when using prefers-color-scheme and detecting dark mode:
Using the existing theme as much as possible.
I don't want to have a style.css and a style-dark.css if I can avoid it. Otherwise it'd be a maintenance nightmare.
Make it work on all my sites
I have three logical sites that look like two to you, Dear Reader. I have hanselman.com, hanselman.com/blog, and hanselminutes.com. They do share some CSS rules but they are written in different sub-flavors of ASP.NET
Consider 3rd party widgets
I use a syntax highlighter (very very old) for my blog, and I use a podcast HTML5 player from Simplecast for my podcast. I'd hate to dark mode it all and then have a big old LIGHT MODE podcast player scaring people away. As such, I need the context to flow all the way through.
Consider the initial state of the page as well as the stage changing.
Sure, I could just have the page look good when you load it and if you change modes (dark to light and back) in the middle of viewing my page, it should also change, right? And also consider all the requirements above.
You can set your Chrome/Edge browser to use System Settings, Light, or Dark. Search for Theme in Settings.
All this, and I can only do it on my lunch hour because this blog isn't my actual day job. Let's go!
The prefers-color-scheme CSS Media Query
I love CSS @media queries and have used them for many years to support mobile and tablet devices. Today they are a staple of responsive design. Turns out you can just use a @media query to see if the user prefers dark mode.
@media (prefers-color-scheme: dark) {
Sweet. Anything inside here (the C in CSS stands for Cascading, remember) will override what comes before. Here's a few starter rules I changed. I was just changing stuff in the F12 tools inspector, and then collecting them back into my main CSS page. You can also use variables if you are an organized CSS person with a design system.
These are just a few, but you get the idea. Note the .line-tan example also where I say 'just put it back to it's initial value.' That's often a lot easier than coming up with "the opposite" value, which in this case would have meant generating some PNGs.
@media (prefers-color-scheme: dark) { body { color: #b0b0b0; background-color: #101010; } .containerOuter { background-color: #000; color: #b0b0b0; } .blogBodyContainer { background-color: #101010; } .line-tan { background: initial; } #mainContent { background-color: #000; } ...snip... }
Sweet. This change to my main css works for the http://hanselman.com main site. Let's do the blog now, which includes the 3rd party syntax highlighter. I use the same basic rules from my main site but then also had to (sorry CSS folks) be aggressive and overly !important with this very old syntax highlighter, like this:
@media (prefers-color-scheme: dark) { .syntaxhighlighter { background-color: #000 !important } .syntaxhighlighter .line.alt1 { background-color: #000 !important } .syntaxhighlighter .line.alt2 { background-color: #000 !important } .syntaxhighlighter .line { background-color: #000 !important } ...snip... }
Your mileage may vary but it all depends on the tools. I wasn't able to get this working without the !important which I'm told is frowned upon. My apologies.
Detecting Dark Mode preferences with JavaScript
The third party control I use for my podcast is a like a lot of controls, it's an iFrame. As such, it takes some parameters as URL querystring parameters.
I generate the iFrame like this:
<iframe id='simpleCastPlayeriFrame' title='Hanselminutes Podcast Player' frameborder='0' height='200px' scrolling='no' seamless src='https://player.simplecast.com/{sharingId}' width='100%'></iframe>
If I add "dark=true" to the querystring, I'll get a different player skin. This is just one example, but it's common that 3rd party integrations will either want a queryString or a variable or custom CSS. You'll want to work with your vendors to make sure they not only care about dark mode (thanks Simplecast!) and that they have a way to easily enable it like this.
But this introduce some interesting issues. I need to detect the preference with JavaScript and make sure the right player gets loaded.
I'd also like to notice if the theme changes (light to dark or back) and dynamically change my CSS (that part happens automatically by the browser) and this player (that's gotta be done manually, because dark mode was invoked via a URL querystring segment.)
Here's my code. Again, not a JavaScript expert but this felt natural to me. If it's not super idiomatic or it just sucks, email me and I'll do an update. I do check for window.matchMedia to at least not freak out if an older browser shows up.
if (window.matchMedia) { var match = window.matchMedia('(prefers-color-scheme: dark)') toggleDarkMode(match.matches); match.addEventListener('change', e => { toggleDarkMode(match.matches); }) function toggleDarkMode(state) { let simpleCastPlayer = new URL(document.querySelector("#simpleCastPlayeriFrame").src); simpleCastPlayer.searchParams.set("dark", state); document.querySelector("#simpleCastPlayeriFrame").src= simpleCastPlayer.href; } }
toggleDarkMode is a method so I can use it for the initial state and the 'change' state. It uses the URL object because parsing strings is so 2000-and-late. I set the searchParams rather than .append because I know it's always set. I set it.
As I write this I supposed I could have stored the document.querySelector() like I did the matchMedia, but I just saw it now. Darn. Still, it works! So I #shipit.
I am sure I missed a page or two or a element or three so if you find a white page or a mistake, file it here https://github.com/shanselman/hanselman.com-bugs/issues and I'll take a look when I can.
All in all, a fun lunch hour. Thanks Stevö for the nudge!
Now YOU, Dear Reader can go update YOUR sites for both Light Mode and Dark Mode.
Sponsor:  The No. 1 reason developers choose Couchbase? You can use your existing SQL++ skills to easily query and access JSON. That’s more power and flexibility with less training. Learn more.
© 2021 Scott Hanselman. All rights reserved.
Tumblr media Tumblr media Tumblr media Tumblr media
     How to detect if the User's OS prefers dark mode and change your site with CSS and JS published first on https://deskbysnafu.tumblr.com/
0 notes
philipholt · 3 years
Text
How to detect if the User's OS prefers dark mode and change your site with CSS and JS
Tumblr media
I got a tweet from Stevö John who said he found my existing light theme for my blog to be jarring as he lives in Dark Mode. I had never really thought about it before, but once he said it, it was obvious. Not only should I support dark mode, but I should detect the user's preference and switch seamlessly. I should also support changing modes if the browser or OS changes as well. Stevö was kind enough to send some sample CSS and a few links so I started to explore the topic.
There's a few things here to consider when using prefers-color-scheme and detecting dark mode:
Using the existing theme as much as possible.
I don't want to have a style.css and a style-dark.css if I can avoid it. Otherwise it'd be a maintenance nightmare.
Make it work on all my sites
I have three logical sites that look like two to you, Dear Reader. I have hanselman.com, hanselman.com/blog, and hanselminutes.com. They do share some CSS rules but they are written in different sub-flavors of ASP.NET
Consider 3rd party widgets
I use a syntax highlighter (very very old) for my blog, and I use a podcast HTML5 player from Simplecast for my podcast. I'd hate to dark mode it all and then have a big old LIGHT MODE podcast player scaring people away. As such, I need the context to flow all the way through.
Consider the initial state of the page as well as the stage changing.
Sure, I could just have the page look good when you load it and if you change modes (dark to light and back) in the middle of viewing my page, it should also change, right? And also consider all the requirements above.
You can set your Chrome/Edge browser to use System Settings, Light, or Dark. Search for Theme in Settings.
All this, and I can only do it on my lunch hour because this blog isn't my actual day job. Let's go!
The prefers-color-scheme CSS Media Query
I love CSS @media queries and have used them for many years to support mobile and tablet devices. Today they are a staple of responsive design. Turns out you can just use a @media query to see if the user prefers dark mode.
@media (prefers-color-scheme: dark) {
Sweet. Anything inside here (the C in CSS stands for Cascading, remember) will override what comes before. Here's a few starter rules I changed. I was just changing stuff in the F12 tools inspector, and then collecting them back into my main CSS page. You can also use variables if you are an organized CSS person with a design system.
These are just a few, but you get the idea. Note the .line-tan example also where I say 'just put it back to it's initial value.' That's often a lot easier than coming up with "the opposite" value, which in this case would have meant generating some PNGs.
@media (prefers-color-scheme: dark) { body { color: #b0b0b0; background-color: #101010; } .containerOuter { background-color: #000; color: #b0b0b0; } .blogBodyContainer { background-color: #101010; } .line-tan { background: initial; } #mainContent { background-color: #000; } ...snip... }
Sweet. This change to my main css works for the http://hanselman.com main site. Let's do the blog now, which includes the 3rd party syntax highlighter. I use the same basic rules from my main site but then also had to (sorry CSS folks) be aggressive and overly !important with this very old syntax highlighter, like this:
@media (prefers-color-scheme: dark) { .syntaxhighlighter { background-color: #000 !important } .syntaxhighlighter .line.alt1 { background-color: #000 !important } .syntaxhighlighter .line.alt2 { background-color: #000 !important } .syntaxhighlighter .line { background-color: #000 !important } ...snip... }
Your mileage may vary but it all depends on the tools. I wasn't able to get this working without the !important which I'm told is frowned upon. My apologies.
Detecting Dark Mode preferences with JavaScript
The third party control I use for my podcast is a like a lot of controls, it's an iFrame. As such, it takes some parameters as URL querystring parameters.
I generate the iFrame like this:
<iframe id='simpleCastPlayeriFrame' title='Hanselminutes Podcast Player' frameborder='0' height='200px' scrolling='no' seamless src='https://player.simplecast.com/{sharingId}' width='100%'></iframe>
If I add "dark=true" to the querystring, I'll get a different player skin. This is just one example, but it's common that 3rd party integrations will either want a queryString or a variable or custom CSS. You'll want to work with your vendors to make sure they not only care about dark mode (thanks Simplecast!) and that they have a way to easily enable it like this.
But this introduce some interesting issues. I need to detect the preference with JavaScript and make sure the right player gets loaded.
I'd also like to notice if the theme changes (light to dark or back) and dynamically change my CSS (that part happens automatically by the browser) and this player (that's gotta be done manually, because dark mode was invoked via a URL querystring segment.)
Here's my code. Again, not a JavaScript expert but this felt natural to me. If it's not super idiomatic or it just sucks, email me and I'll do an update. I do check for window.matchMedia to at least not freak out if an older browser shows up.
if (window.matchMedia) { var match = window.matchMedia('(prefers-color-scheme: dark)') toggleDarkMode(match.matches); match.addEventListener('change', e => { toggleDarkMode(match.matches); }) function toggleDarkMode(state) { let simpleCastPlayer = new URL(document.querySelector("#simpleCastPlayeriFrame").src); simpleCastPlayer.searchParams.set("dark", state); document.querySelector("#simpleCastPlayeriFrame").src= simpleCastPlayer.href; } }
toggleDarkMode is a method so I can use it for the initial state and the 'change' state. It uses the URL object because parsing strings is so 2000-and-late. I set the searchParams rather than .append because I know it's always set. I set it.
As I write this I supposed I could have stored the document.querySelector() like I did the matchMedia, but I just saw it now. Darn. Still, it works! So I #shipit.
I am sure I missed a page or two or a element or three so if you find a white page or a mistake, file it here https://github.com/shanselman/hanselman.com-bugs/issues and I'll take a look when I can.
All in all, a fun lunch hour. Thanks Stevö for the nudge!
Now YOU, Dear Reader can go update YOUR sites for both Light Mode and Dark Mode.
Sponsor:  The No. 1 reason developers choose Couchbase? You can use your existing SQL++ skills to easily query and access JSON. That’s more power and flexibility with less training. Learn more.
© 2021 Scott Hanselman. All rights reserved.
Tumblr media Tumblr media Tumblr media Tumblr media
     How to detect if the User's OS prefers dark mode and change your site with CSS and JS published first on http://7elementswd.tumblr.com/
0 notes
storydevs · 6 years
Text
Logging Breakdown
It’s almost certain that any code you write will have a bug in it. There’s a lot things that can help with finding them and one of those things is logging to the console. Most programming languages have a function called something like “print” or “log” to output data and messages while the program is running.
Tumblr media
The way logging works on StoryDevs is a little more complicated. For brevity I’m just going to describe how logging works in the browser and skip how it’s done on the server.
Simple Logging
In JavaScript we use the console object which has a few different ways to log things. For example if you have a script with a line of code that reads:
console.log(“Hi there!”);
If you open up Chrome’s dev tools (shortcut is F12) and go to the “Console” tab you’ll see this:
Tumblr media
Note how it says “script.js:2342” on the far right. This tells us where the line of code that logged this information is. It can be useful when you’re trying to figure out where an error is coming from, especially if you have thousands of lines of code. The “script.js” part refers to the file name and “2342” is a line in that file.
Default Logging Is Nice
The default methods for console are nice because you can log things other than just text. You can essentially log anything and it’ll look pretty good in the console. For example let’s say we have the following array:
let a = [“Some string”, 52, true];
And then we log it:
console.log(a);
The console will output this:
Tumblr media
Any time you log something like an array or an object you’ll be able to expand it to see what it contains. Again, useful for debugging.
I Log A Lot
So much, in fact, that I find typing “console.log()” kind of annoying. So I made a function called “log” which works exactly the same and just has a different name:
Tumblr media
There’s actually another way to do this which is:
let log = console.log;
Either way you can now write:
log(“My message…”);
And it’ll work. The second way actually avoids a problem I’m about to show you with the first approach but we’re doing it the first way to illustrate a point.
Remember how console.log tells you the file and the line you logged from? Well the problem with creating your own function named “log” and then calling console.log inside it is that it’ll always list the same line: the one that console.log is on.
So let’s say we have the following code:
Tumblr media
This is what the result will be:
Tumblr media
Notice how on the right it says the array was logged from line 3, not line 7 where we actually did our logging. In fact, if you defined the log function in another file it’d even list that file instead of the one you logged from. This isn’t what we want! So why did I do it this way and how do I get around it?
Why I’m Doing It The Hard Way: Part 1
To explain this I need to show you how I work. When I write JavaScript for StoryDevs I try to sort the code into a few broad categories and then make each category its own file. So here’s my JavaScript folder (there’s three other folders inside it but just ignore those):
Tumblr media
Each file does stuff related to its name. For example, columns.js contains all the code related to StoryDevs’ columns. When the site is public I don’t want all the code split up like this.
Firstly, it makes understanding the code a lot easier because the code is logically organised. StoryDevs will skew left (politically speaking) and I don’t want it to be easy to make a “without-the-politics” (i.e., right-leaning in this climate) knock-off of StoryDevs. I want them to have to cobble together disparate code or write it themselves :)
The second reason is that one big file compresses better than several smaller files. The basics of compression is that it finds a repeating pattern in the text and then replaces it with a smaller code. To allow for uncompressing a little dictionary is kept which tells us what pattern each code refers to.
Let’s say we have this file:
Tumblr media
If we zip this it’s smaller than if you have two zipped files with the functions split between them. The larger the files get the more true this is. Combining all my JavaScript files into one big file and then compressing it results in a 10% smaller zip. That’s a decent saving for a file that will be requested a lot.
The third reason is it’s just nicer to only have to link to one script file! I don’t have to remember to include a new JavaScript file if I happen to make a new one.
What Does This Have To Do With Logging!
Remember earlier when we logged something and it showed us the line number and the file name? Well if you combine all your files into one big file before it’s sent that means the logging info will be incorrect. It will log the big file’s name (I simply call it “script.js”) and the line number won’t be the original line number.
So if we have a file, “little_1.js”:
Tumblr media
And we write a helper program that joins it with “little_2.js” (this is basically what I do on the server):
Tumblr media
We’ll get this:
Tumblr media
What was previously line 1 in “little_2.js” is now line 10 in our new automatically generated script. The script itself doesn’t know which parts of it originally belonged to which file. Both these things make debugging harder. So to get around this I add a little extra info at the bottom of my big script file:
Tumblr media
As I build the single script file from the smaller script files I save each file’s name and the number of lines it contains to an object. Then I write this object at the very end of the file. Using this, a bit of math allows us to figure out the appropriate name and number to use when logging.
Why I’m Doing It The Hard Way: Part 2
Okay now I’m actually going explain this! Remember how there’s two ways to create a function called “log”? There was this way:
Tumblr media
And this way:
let log = console.log;
And the first one has a problem in that it will also think the logging is occurring on the line where console.log is rather than from where you’re calling log from. Despite this, I chose to do it that way because I need to do that math to work out the file name and line number anyway before logging.
If you look at the second approach to creating a log function, all it’s doing is saying “‘log’ now means ‘console.log’” — it doesn’t allow us to jam more code into it. Whereas in the first approach you can write as much code as you want before the logging takes place. And boy do I do that:
Tumblr media
Let’s break this down. First I start out by creating an error object. I’m doing this because an error object contains the stack property. Now, in programming there’s something called the “call stack” and this is what stack refers to. It’s a list of all the functions that were called to get to this point in your code.
Tumblr media
Here’s an example of what it looks like if we log err.stack:
Tumblr media
Keep in mind it starts from the most recent function call. If you were to say this in plain English you might say, “There was an error in the ‘log’ function which was called by ‘init_actionables’ which itself was called by ‘dynamic_content_init’ [. . .]” and so on.
The err.stack property of an error is a string, which means you can call string methods on it. For example, we could do err.stack.toLowerCase() which would make all the text it logs lower case. In my case I call split on it:
Tumblr media
First, what’s “\n” mean? That’s an invisible character computers use to mark where a new line begins. It’s inserted every time you hit your enter key. See how when we logged err.stack above it’s on multiple lines? That means the string contains “\n” characters.
When I call the string’s split method and pass in “\n” it means “split this string where the new line characters are”. It results in you getting back an array of strings. So if we log err.stack.split(“\n”) we get this:
Tumblr media
Instead of one long string we now have six strings. Because we divided the original string by its lines, we now have the name of one function per line as well as the file name and line number it was called from. (The exception is the first string that just says “Error.”)
So, err.stack.split(“\n”) results in an array of strings. Because this error was created inside the log function we know the first function will always be log. The one after that (the third element) will always contain a string describing the function that called log.
Tumblr media
So we get the third index of the array (which is 2 because it starts from 0) and then call trim on it. The trim function just gets rid of whitespace padding on the left or right of a string. As you can see above there’s some leading whitespace that we don’t want.
Finally, we assign the result of all these operations to line. So right now line contains the string:
“at init_actionables (http://localhost:8080/js/script.js:2532:5)”
What we want from this string is the function name and the line number. So with the next bit of code we start to extract the line number:
Tumblr media
We’re take the string we assigned to line, call the split method on it (passing it a space character), and then store the result in parts. After this the contents of parts is an array containing separate strings that were previously joined by spaces:
Tumblr media
(Incidentally, this is why I called trim beforehand — there would be four empty strings before “at” because of the four leading spaces. So I got rid of them to make the array easier to think about.)
Okay, let’s speed things up a bit. The next few lines are doing something similar to the previous ones:
Tumblr media
First we grab the last element in the parts array and assign it to source. To get the last element of an array you have to get the arrays length (parts.length) and then subtract one from it. The last index of an array that is 3 elements long is “2” as most programming languages have arrays that count from zero.
That means source now contains the string:
“(http://localhost:8080/js/script.js:2532:5)”
Next, we break source into parts, dividing it anywhere a “:” appears. Note that I name it “source_parts” instead of overwriting parts because I still need parts for something I’ll do later. So source_parts now looks like this:
Tumblr media
Then we grab the fourth element (index 3) and assign it to abs_line (the name stands for “absolute line”). This is the line number of where log was called in the big script we built earlier. Now abs_line contains “2532” as a string value. The next part looks complicated but it’s not too bad.
Tumblr media
First we define some variables source_file, rel_line, and total. I give total a default value of “0” because I’m gonna do math with it. The reason I define these outside the loop is that any variable created inside the loop only exists for that iteration of the loop. I need total (and the other variables) to persist after that.
Next we start the loop. The object script_meta was the thing we defined at the very end of the big script that listed all the names of the JavaScript files and how many lines they contain. It looked like this:
Tumblr media
Each time we loop, the fn variable (which stands for “filename”) is assigned a key from the script_meta object, starting from “column.js” through to “tools.js.” Next we assign the result of subtracting total from abs_line to rel_line (“rel_line” stands for “relative line”). Since abs_line is 2532 and total is 0 we get 2532.
UTTERLY POINTLESS YOU FOOL. Well hey hold on. Next we grab the total line count associated with the current file by indexing script_meta with fn. If this were the first iteration of the loop fn would be “column.js” so script_meta[fn] would result in 526. Then we add this to total, making it 526 as well. Then…
Tumblr media
...we have this little conditional. It says “if the total so far is higher than the absolute line (the line we logged from in the big file) then do this.” Then we say source_file is the current file name and use break, a keyword for ending loops early and continuing with the rest of the code after the loop.
In essence what we’re doing is going through script_meta and adding each file’s line count to total. Then we check if total has become higher than the line number we logged from in the big script file. If it has, we know that it must have originally been in this file because all the scripts were added together in alphabetical order.
The abs_line we logged from was 2532. Let’s visualise what the loop does:
Tumblr media
Here we can see that once we get to “main.js” our total line count jumps to 4121, which is above abs_line’s 2532. That means the line was originally in the file “main.js” before we joined it together with the others. So our conditional tests true and kicks us out of the loop with break.
Now the two variables defined outside the loop (source_file and rel_line) contain the original source file name and the correct line number relative to the original file. That thing we were doing at the beginning of the loop:
rel_line = abs_line - total;
Was to figure out what the original line number was. If you subtract the total line count of the files so far from the line you logged from in the big file you’ll wind up with the original line. It’s telling us what the line number would be if you were logging from that file.
This results in source_file being “main.js” and rel_line being 192:
2532 - (526 + 1690 + 124) = 192
Christ, Can You Break This Up With Another Header Or Something
Yeah, sorry. I honestly didn’t think this wouldn’t take so long. I regret this post and my life as wel , ,
A Nicer Section
Next, a simpler part of the log function:
Tumblr media
Again, we’re defining a variable before using it in the conditionals below so that it still exists outside those blocks. Then we ask if parts is longer than 2. What the hell is parts?! This is the thing we were saving for later. It’s the array we got by pulling out a line from the error’s call stack:
Tumblr media
We’re checking its length because it can either be 2 or 3. In this case the function on this line has a name “init_actionables” but there’s a thing in JavaScript (and other languages) called an “anonymous function.” Basically they’re functions without names. If the function is anonymous parts will have a length of 2.
So if parts has a length of 2 we make the caller’s name “anonymous” otherwise we grab the second item and make that the caller’s name. Either way we now have a name!
Lastly, we have this:
Tumblr media
The console object has methods other than just log. The group and groupEnd methods mark the start and end of a group respectively when logging to the console. Anything you log to the console after calling group will be nested under the heading you give it.
And that means the result of calling log like this:
Tumblr media
Shows up in the console like this:
Tumblr media
Woohoo! We have the correct file name, line number, and even the function name that log was called within. Over to the right you’ll see it says 5234 which is where console.group and console.log are logging from in the script file (which we don’t care about!)
As with the original console.log we can still log complex objects and have them display nicely:
Tumblr media
Summary
That’s a lot so let’s recap:
Logging is useful for debugging.
StoryDevs has multiple JavaScript files. Before sending them to the user they’re combined into one big file because it compresses better, among other reasons.
A little bit of metadata that preserves the file names and their line counts is saved at the end of the big file.
When you use console.log the console will show you which file logged the message and from what line.
That file name and line number will be incorrect because we combined all the files into one big file.
Therefore, we need to do a little bit of parsing and math to work out the original file name and line number, using the metadata we saved earlier.
Conclusion
Well that’s it. It should be noted that I wrote this for myself in one afternoon so it’s not intended to be super robust. It’s only been tested in Chrome and I don’t care if it doesn’t work perfectly elsewhere at the moment.
Anyway, I hope someone finds this interesting/useful because my wrists hurt!
StoryDevs is a place for developers of story-focused games and visual novels to find each other and collaborate. The site is under development but handle reservations are open: www.storydevs.com/reserve
Website: www.storydevs.com Patreon: https://www.patreon.com/jakebowkett Twitter: https://twitter.com/storydevs Discord: https://discord.gg/A2jtNqE Email: [email protected]
7 notes · View notes
thanhtuandoan89 · 3 years
Text
Avoiding False Conversions in Google Analytics
Posted by R0bin_L0rd
Preface
The first half of this post is a quick rundown of some of the standard ways in which your conversions could be going awry.
The second half of this post — everything after “How to filter conversions with Tag Manager” is an advanced way of intelligently filtering conversions using Tag Manager and cookies.
If you’re confident you’ve already covered your bases, feel free just to skip to the advanced section, I just feel it’s important to go through some of the basic stuff before diving into more complex solutions.
Avoiding false conversions
Aside from failing to record important data, one of the best ways to screw up your analytics is to record the wrong thing and lump it in with all the times you’ve recorded the right thing.
For example: if you’re counting conversions when you shouldn’t be, that can screw up automated ad bidding, how much you value individual channels, or even how well you think your business is doing. For this post, we’ll be referring to this issue as “false conversions”.
There are a huge number of ways you can track conversions in Google Analytics, and a huge number of ways to screw it up. This post is going to focus on some of the main ways you can mess up conversions when you’re basing them on users completing a form and then landing on a thank-you page.
We’ll cover:
Some useful tools
Things to check — how might users be accidentally converting?
How to protect destination-based goals from false conversions
An ideal event-based goal approach
How to protect event-based goals from false conversions
Useful tools
The tools below will help you with some of the checks in this post.
Chrome DevTools
F12 will open Chrome DevTools (you may need to press the “function” key depending on your keyboard). You can test JavaScript in “Console”, and view active cookies in “Application”.
Google Tag Manager preview
Google Tag Manager has a new preview which will show you what happens on a series of pages over time.
Adswerve dataLayer Inspector
This plugin summarizes dataLayer information in Chrome Console.
Analytics Tracking Monitor plugin
I’ve found this plugin really useful for checking what information is being sent to GA. One nice feature is being able to block hits from actually being sent to GA while recording what would be sent.
Tag Assistant
The Chrome Tag Assistant plugin will show you what Tag Manager tags are present on the page. If you click to record the session, it’ll also give you a breakdown of everything that’s happened on each page. That said — I don’t tend to rely on the recordings as much if I have Tag Manager access, because a lot of the useful information is covered between the new GTM preview and the tracking monitor plugin.
Tag Mapper
I created a free Tag Mapper tool to make it easier to see what impact Tag Manager changes might have. If you’re planning on changing something in your GTM account, you can see what else might be impacted. Likewise, if you’ve noticed that something is broken, it can help you find the root cause.
Things to check
It can be tempting to leap straight to a catch-all solution, but if you’re recording conversions when you shouldn’t be, that could be because your website visitors are doing things they shouldn’t be.
Let’s start with a quick rundown of checks you should do to make sure you’re not making the numbers look right by just ignoring problems on your site.
1. Are you only recording conversions on thank-you pages?
To check if you’re recording conversions on pages you shouldn’t be (like, every page on your site or something) have a quick look at the Reverse Goal Path report in Google Analytics:
Conversions > Goals > Reverse Goal Path.
The first column on the left should show you where your goal conversions are taking place, unless you’re doing something unusual. If you’re seeing a bunch of pages in that column which you don’t expect, that’s a sign you need to change your criteria for conversions.
One thing to bear in mind here: if you’re recording conversions based on events rather than pageviews, and you’re seeing the wrong page appearing in that left-hand column, make sure your conversion event only ever fires after your pageview.
2. Are you linking to conversion pages in other ways besides form completions?
If you’re using any goals based on a user loading a specific page (like a thank-you page), and you know you’re only recording conversions on thank-you pages, another way you could be screwing things up is accidentally linking to those thank-you pages. If a user can click on the wrong link and end up on a conversion page, you need to fix that.
One way to check for this is using a tool like Screaming Frog to crawl the site and just see if your conversion pages appear. If they appear at all, you know that’s probably a problem. To find out how to fix the problem, you can select the offending pages and check the “Inlinks” panel, which will give you a list of where you’re linking to them.
3. Are users landing directly on thank-you pages?
A quick way to check if users are landing on your thank-you pages is to use segments. If you create a segment where the landing page is your thank-you page, you can get an idea of how often Google Analytics thinks users are landing on your conversion page.
Below, you can see a screenshot of the segment interface. I’ve set it to include any session where the first interaction was a user landing on a thank-you landing page. As you can see, that was the case for 339 sessions on this site:
Once you see how often users are landing on your thank-you pages, you can pinpoint the sources which are bringing those users to the site.
Below, I’ve applied a “lands on thank-you page” segment to the Source/Medium report, and it looks like we’re getting a bunch of direct sessions, but also some CPC sessions, and organic sessions elsewhere, too:
An important thing to bear in mind here is that this is based on what Google Analytics thinks is happening. It doesn’t necessarily mean users are landing on these pages directly from adverts. In fact, in this example, we know this isn’t always the case, and sometimes it’s a symptom of our tracking code being broken or confused in another way. Even so, it gives us some things to investigate.
For example:
Do we have adverts or other activity pointing straight to conversion pages?
Are our conversion pages indexed in Google?
Do we have a page in the middle of our conversion flow that isn’t being tracked?
Is our tracking code broken, or are users doing things on-site which would confuse GA?
3.1 Do you have adverts or other activity pointing straight to conversion pages?
I won’t be able to walk you through all of this, but all advertising platforms should allow you to check active landing pages. It’s also important to make sure that you don’t have any affiliates linking directly to conversion pages — either accidentally or maliciously — as you could be paying them a lot more than they deserve.
It may be harder to check non-paid links, like social media activity. That said, it’s worth spending the time checking. If you find you’re linking to these conversion pages by accident, you can work with relevant teams to put policies in place for that in future.
3.2 Are your conversion pages indexed in Google?
Google can be a frequent cause of conversion page issues. It’s a ravenous crawler. It’ll follow links inside and outside of your site, and if there’s a machine-crawlable link to your thank-you page, it’ll probably find it.
A quick way to check if Google has saved your thank-you pages (and might be sending users straight to them) is to search for the pages in Google.
Using “site:” filters Google results to just pages on your site. Using “inurl:” filters results to just pages that contain a specific string.
Below is an example of a check we did for one of our clients. We found that they had a lot of “thank-you” pages in the index (over 600). Some of those pages were fine, but it highlighted a number of conversion pages for us to deal with:
3.3 Is your tracking code broken, or are users doing things on-site which would confuse GA?
We don’t have time to go through all the things that could go wrong here. Some things to check are:
Are you missing tracking code on some pages? Perhaps you’re failing to record the user before they land on the thank-you page.
Do you have different versions of Google Analytics on different pages? This can, again, cause confused or split sessions.
Are you including UTM parameters on any internal links? Any website crawler should help you find this.
Do you have the wrong timezone set in GA? Sessions can’t cross “midnight” — if they do, GA will split them into two separate sessions.
Are you including important information on the thank-you page that could cause users to bookmark the page, or try to come back to it later? One solution here is to include pretty much nothing visitor-specific on the thank-you page, and assure them that you’ll email them details. It’s worth testing this to make sure it doesn’t hurt visitor confidence.
Do you have any forms, that take more than half an hour to fill out, and don’t record interactions in the meantime? You can avoid this by splitting the form into different pages and tracking when visitors fill out a form field or when they hit errors. Entirely aside from what we’re looking at in this post, but all of these things should help you make your forms more user-friendly.
Once you have all of those checked off, you can start to look at ways to improve the way you filter your conversion data.
How to protect destination-based goals from false conversions
If you have your goal type set to “Destination” in Google Analytics, that means that any time GA records a pageview for a specific page, it’ll count as a conversion.
You can make your destination goals require users to have visited other pages first by using a funnel. If you edit the goal and switch “Funnel” on, you can specify the steps leading up to the goal. This means you can make sure that you don’t record goal conversions when users land directly on your thank-you pages.
You can also use it to separate out different kinds of goal conversions. For example, if you use the same thank-you page for multiple forms, you could have one goal where the funnel involves traveling through one form page, and another goal which involves traveling through another.
This will work if you:
Have a smaller (and fairly static) number of different goals.
There is a small (and fairly static) number of ways users can legitimately complete each goal.
However, funnel steps don’t allow things like regex, so they aren’t very flexible. Also, you can only use funnels with destination-type goals. So, funnels won’t help if:
Your goals are event-based.
You have lots of ways users could reach a goal.
You have multiple teams managing the site, and it doesn’t make sense to keep track of all the ways users could reach a goal.
You should be aware that if you have a problem like internal UTMs or sessions timing out, these form funnels can mean you stop recording some conversions you should be. Seriously, make sure those problems are fixed.
The ideal approach: event-based goals
The ideal approach involves using event-based conversions rather than destination-based ones. You work with your developers so that as the users complete the form you tell GA that an event has occurred, rather than GA having to wait for a thank-you page pageview. GA then records each instance of that event as a Goal conversion.
Below is the criteria for one event-based goal conversion, if you haven’t seen them before and are struggling to picture how they’re set up. It records a conversion for this goal any time GA receives an event of the category “thank_you_page”:
The reason this is ideal is, you’ll only record a conversion when the user actually does what you want them to do. Most conversion goals based on pageviews are just us trying to guess what the user has done. That’s why you run into problems with destination-based goals, like users landing directly on your thank-you page without completing the form you wanted them to complete.
You might think it’s a bit strange to leave this “ideal” solution until so late in the post, but I’m doing so because this is often not the simplest solution. It can require the most work on the developer side, and you could be using something built into your CMS that your dev team has to edit, or even worse, you could be working with an external form solution that they have to hack their way into.
I’m bringing this solution up at this point because if you don’t already have this in place, you’ll need to convince someone to do it. Their first question may be “have you considered other options?” When you have that conversation, you can say:
We’ve made sure we’re only recording conversions on the right pages.
We’ve made sure users aren’t getting to those pages in ways we can prevent.
We’ve made sure there aren’t other issues with how we’re tracking the site.
Our conversion data is being polluted in a way we can’t prevent because we have to rely on thank-you pageviews.
We can’t filter out those conversions using Google Analytics.
The best way to make sure our data is accurate is to use events, and the most accurate events to use are ones that only occur when the user does exactly what we want them to.
If you can help me I’ll be your best friend.
An alternative to Google Analytics funnels
It could turn out that the events-based solution above is impossible. Life has its frustrations, we soldier on.
An alternative is to switch to event-based conversions anyway and use Tag Manager to handle it all yourself. Using Tag Manager and cookies, you can create a more flexible version of GA’s funnel to only send conversion events when users land on a thank-you page having visited a qualifying page. How does that work? In short:
When a user visits one of your qualifying pages, you put a cookie in their browser.
When the user loads a thank-you page, you check for the cookie, and, if it exists, you send a conversion event to Google Analytics. If it doesn’t, you don’t.
Then you clear the cookie.
That means you won’t record the following false conversions:
Users landing direct on thank-you pages.
Users accidentally clicking to thank-you pages when they haven’t visited the relevant form.
Users leaving the thank-you tab open, or bookmarking it, and clicking back to it later after their GA session expires.
The section below gets into some specific Tag Manager terminology (the most confusing being that a “Custom Event” and a “Google Analytics Event” are two different things entirely).
Some terminology to know
I’ve color coded Tag Manager terminology in blue and all Google Analytics terminology in orange, but if you find yourself getting lost, you might want to read around a bit or talk to a knowledgeable colleague or consultant.
Event: Something we send to Google Analytics to record a specific action.
Custom event: Something that happens on the web page, which we can use as part of the criteria for a Tag Manager trigger.
Trigger: A set of conditions we lay out in Tag Manager. When these conditions are all fulfilled at the same time, the trigger fires and usually activates a tag.
Tag: Something in Tag Manager that does something. This sounds vague because it could be almost anything from sending an event to Google Analytics to completely rewriting the page.
Variable: A piece of information in Tag Manager that we can easily reference in triggers, tags, or other variables.
Data layer: Structured information on the page which makes it easier to pass information to Tag manager.
How to filter conversions with Tag Manager
1. Make sure Google Tag Manager is installed on your site
It’ll need to be on every page. Google has shared a Tag Manager quick-start guide if you need further guidance.
If you’re switching from standard GA code to Tag Manager, make sure you don’t include both GA and Tag Manager, or you’ll double-count.
2. Tell Tag Manager every time a thank-you page is loaded
We’ll assume your thank-you pages are all the same type of page, so you can reasonably say to your dev team, “please make this change to all of our thank you pages”. Ask them to add something like the script below.
Example script <script> window.dataLayer.push({    "event": "conversion" }); </script>  
If you need to test this process before getting the devs involved, you can try adding the code yourself by pasting it into the console using Chrome DevTools.
When the page loads, that script will add information to the data layer. Tag Manager will detect the change, and you can use it as one of the conditions for a trigger. In this case, Tag Manager would detect a Custom Event called conversion as this data is added. We’ll come back to that.
3. Tell Tag Manager every time a qualifying page is loaded
We’ll also assume there are some similarities between your qualifying pages. For one thing, they’ll probably all have a form on them. You can coordinate with your dev team to automatically add/activate a script any time one of those forms is added.
Example script <script> window.dataLayer.push({  "event": "qualifying" }); </script>
In this case, you’d see a Custom Event called qualifying. Again, you can test this by pasting directly into Console.
4. Whenever a user lands on a qualifying page, set a cookie
You’ll use your “qualifying” Custom Event as the criteria for a trigger. Below is a screenshot of the trigger setup:
Then you’ll create a tag which will be activated by that trigger. The tag will add some content to the page, in this case adding JavaScript (even though the tag type specifies HTML). The JavaScript will run as soon as it’s added and set a cookie for the user, that way you can pass information from one page to another.
Example script <script> // Get time 30 minutes from now (this is because the default GA session timeout // is half an hour and we want our cookie timeout to match) var dt = new Date(); dt.setHours( dt.getHours() + 0.5 );
// Set a cookie called ‘qualified’ with the value being ‘true’ which expires in 30 minutes document.cookie = "qualified=true; path=/; expires="+dt; </script>
5. Get the cookie value
Use a Tag Manager variable to make sure you’re detecting the value of the cookie, which will give you the current value of your “qualified” cookie each time you check.
6. Determine whether you should filter the conversion
In step two, you created a dataLayer event that will occur on all of your final conversion pages.
Now you create a trigger which fires on your “conversion” event.
Then create a tag which is activated by that trigger, and creates another Custom Event.
Below is the custom HTML to add. It checks if your qualifying cookie is set to “true”, which shows the user has already visited a qualifying page this session. If it is true, you create another Custom Event called “create_filtered_conversion”. If it’s false, you don’t. Either way, delete the cookie by setting its expiry time to be far in the past.
Example script <script> // When we are about to fire a conversion - check if we should. // If we should - create an event that will trigger the conversion // otherwise, don’t. Either way - clear the cookie
// Get variables var isQualified =
// Check if the conversion is qualified if (isQualified === "true"){   // If the user has a qualifying cookie   window.dataLayer.push({   "event": "conversion_confirmed",   }); } else {   // Do nothing if we have determined the conversion shouldn't fire   "" }
// Set cookie expiry in the past to clear it document.cookie = "qualified=false; path=/; expires=Thu, 01 Jan 1970 00:00:00"; </script>
7. Send event to GA
First you create a trigger which is waiting for that “conversion_confirmed” event.
Then you create a tag, activated by the trigger above, which sends the relevant event to GA. The specifics of the event sent to GA can be whatever you want, you just need to make sure they match the criteria of your goal in GA.

8. Don’t switch off your old conversions straight away
One nice thing about this is you can run it alongside your existing conversion tracking to see how often conversions are being filtered out. Keep your old conversion setup running for a while (how long depends on how often you get conversions).
Watch the two numbers and check if you’re filtering out loads of conversions. This check will help you spot mistakes in either the old setup or the new one.
Let me know what you think
Google Analytics will never be a perfect record of everything on your website, but these checks and processes should help you weed out some of the ways it can mislead you.
What do you think? What GA improvements do you think people have been missing? Let me know in the comments or on Twitter @robinlord8.
Sign up for The Moz Top 10, a semimonthly mailer updating you on the top ten hottest pieces of SEO news, tips, and rad links uncovered by the Moz team. Think of it as your exclusive digest of stuff you don't have time to hunt down but want to read!
0 notes
drummcarpentry · 3 years
Text
Avoiding False Conversions in Google Analytics
Posted by R0bin_L0rd
Preface
The first half of this post is a quick rundown of some of the standard ways in which your conversions could be going awry.
The second half of this post — everything after “How to filter conversions with Tag Manager” is an advanced way of intelligently filtering conversions using Tag Manager and cookies.
If you’re confident you’ve already covered your bases, feel free just to skip to the advanced section, I just feel it’s important to go through some of the basic stuff before diving into more complex solutions.
Avoiding false conversions
Aside from failing to record important data, one of the best ways to screw up your analytics is to record the wrong thing and lump it in with all the times you’ve recorded the right thing.
For example: if you’re counting conversions when you shouldn’t be, that can screw up automated ad bidding, how much you value individual channels, or even how well you think your business is doing. For this post, we’ll be referring to this issue as “false conversions”.
There are a huge number of ways you can track conversions in Google Analytics, and a huge number of ways to screw it up. This post is going to focus on some of the main ways you can mess up conversions when you’re basing them on users completing a form and then landing on a thank-you page.
We’ll cover:
Some useful tools
Things to check — how might users be accidentally converting?
How to protect destination-based goals from false conversions
An ideal event-based goal approach
How to protect event-based goals from false conversions
Useful tools
The tools below will help you with some of the checks in this post.
Chrome DevTools
F12 will open Chrome DevTools (you may need to press the “function” key depending on your keyboard). You can test JavaScript in “Console”, and view active cookies in “Application”.
Google Tag Manager preview
Google Tag Manager has a new preview which will show you what happens on a series of pages over time.
Adswerve dataLayer Inspector
This plugin summarizes dataLayer information in Chrome Console.
Analytics Tracking Monitor plugin
I’ve found this plugin really useful for checking what information is being sent to GA. One nice feature is being able to block hits from actually being sent to GA while recording what would be sent.
Tag Assistant
The Chrome Tag Assistant plugin will show you what Tag Manager tags are present on the page. If you click to record the session, it’ll also give you a breakdown of everything that’s happened on each page. That said — I don’t tend to rely on the recordings as much if I have Tag Manager access, because a lot of the useful information is covered between the new GTM preview and the tracking monitor plugin.
Tag Mapper
I created a free Tag Mapper tool to make it easier to see what impact Tag Manager changes might have. If you’re planning on changing something in your GTM account, you can see what else might be impacted. Likewise, if you’ve noticed that something is broken, it can help you find the root cause.
Things to check
It can be tempting to leap straight to a catch-all solution, but if you’re recording conversions when you shouldn’t be, that could be because your website visitors are doing things they shouldn’t be.
Let’s start with a quick rundown of checks you should do to make sure you’re not making the numbers look right by just ignoring problems on your site.
1. Are you only recording conversions on thank-you pages?
To check if you’re recording conversions on pages you shouldn’t be (like, every page on your site or something) have a quick look at the Reverse Goal Path report in Google Analytics:
Conversions > Goals > Reverse Goal Path.
The first column on the left should show you where your goal conversions are taking place, unless you’re doing something unusual. If you’re seeing a bunch of pages in that column which you don’t expect, that’s a sign you need to change your criteria for conversions.
One thing to bear in mind here: if you’re recording conversions based on events rather than pageviews, and you’re seeing the wrong page appearing in that left-hand column, make sure your conversion event only ever fires after your pageview.
2. Are you linking to conversion pages in other ways besides form completions?
If you’re using any goals based on a user loading a specific page (like a thank-you page), and you know you’re only recording conversions on thank-you pages, another way you could be screwing things up is accidentally linking to those thank-you pages. If a user can click on the wrong link and end up on a conversion page, you need to fix that.
One way to check for this is using a tool like Screaming Frog to crawl the site and just see if your conversion pages appear. If they appear at all, you know that’s probably a problem. To find out how to fix the problem, you can select the offending pages and check the “Inlinks” panel, which will give you a list of where you’re linking to them.
3. Are users landing directly on thank-you pages?
A quick way to check if users are landing on your thank-you pages is to use segments. If you create a segment where the landing page is your thank-you page, you can get an idea of how often Google Analytics thinks users are landing on your conversion page.
Below, you can see a screenshot of the segment interface. I’ve set it to include any session where the first interaction was a user landing on a thank-you landing page. As you can see, that was the case for 339 sessions on this site:
Once you see how often users are landing on your thank-you pages, you can pinpoint the sources which are bringing those users to the site.
Below, I’ve applied a “lands on thank-you page” segment to the Source/Medium report, and it looks like we’re getting a bunch of direct sessions, but also some CPC sessions, and organic sessions elsewhere, too:
An important thing to bear in mind here is that this is based on what Google Analytics thinks is happening. It doesn’t necessarily mean users are landing on these pages directly from adverts. In fact, in this example, we know this isn’t always the case, and sometimes it’s a symptom of our tracking code being broken or confused in another way. Even so, it gives us some things to investigate.
For example:
Do we have adverts or other activity pointing straight to conversion pages?
Are our conversion pages indexed in Google?
Do we have a page in the middle of our conversion flow that isn’t being tracked?
Is our tracking code broken, or are users doing things on-site which would confuse GA?
3.1 Do you have adverts or other activity pointing straight to conversion pages?
I won’t be able to walk you through all of this, but all advertising platforms should allow you to check active landing pages. It’s also important to make sure that you don’t have any affiliates linking directly to conversion pages — either accidentally or maliciously — as you could be paying them a lot more than they deserve.
It may be harder to check non-paid links, like social media activity. That said, it’s worth spending the time checking. If you find you’re linking to these conversion pages by accident, you can work with relevant teams to put policies in place for that in future.
3.2 Are your conversion pages indexed in Google?
Google can be a frequent cause of conversion page issues. It’s a ravenous crawler. It’ll follow links inside and outside of your site, and if there’s a machine-crawlable link to your thank-you page, it’ll probably find it.
A quick way to check if Google has saved your thank-you pages (and might be sending users straight to them) is to search for the pages in Google.
Using “site:” filters Google results to just pages on your site. Using “inurl:” filters results to just pages that contain a specific string.
Below is an example of a check we did for one of our clients. We found that they had a lot of “thank-you” pages in the index (over 600). Some of those pages were fine, but it highlighted a number of conversion pages for us to deal with:
3.3 Is your tracking code broken, or are users doing things on-site which would confuse GA?
We don’t have time to go through all the things that could go wrong here. Some things to check are:
Are you missing tracking code on some pages? Perhaps you’re failing to record the user before they land on the thank-you page.
Do you have different versions of Google Analytics on different pages? This can, again, cause confused or split sessions.
Are you including UTM parameters on any internal links? Any website crawler should help you find this.
Do you have the wrong timezone set in GA? Sessions can’t cross “midnight” — if they do, GA will split them into two separate sessions.
Are you including important information on the thank-you page that could cause users to bookmark the page, or try to come back to it later? One solution here is to include pretty much nothing visitor-specific on the thank-you page, and assure them that you’ll email them details. It’s worth testing this to make sure it doesn’t hurt visitor confidence.
Do you have any forms, that take more than half an hour to fill out, and don’t record interactions in the meantime? You can avoid this by splitting the form into different pages and tracking when visitors fill out a form field or when they hit errors. Entirely aside from what we’re looking at in this post, but all of these things should help you make your forms more user-friendly.
Once you have all of those checked off, you can start to look at ways to improve the way you filter your conversion data.
How to protect destination-based goals from false conversions
If you have your goal type set to “Destination” in Google Analytics, that means that any time GA records a pageview for a specific page, it’ll count as a conversion.
You can make your destination goals require users to have visited other pages first by using a funnel. If you edit the goal and switch “Funnel” on, you can specify the steps leading up to the goal. This means you can make sure that you don’t record goal conversions when users land directly on your thank-you pages.
You can also use it to separate out different kinds of goal conversions. For example, if you use the same thank-you page for multiple forms, you could have one goal where the funnel involves traveling through one form page, and another goal which involves traveling through another.
This will work if you:
Have a smaller (and fairly static) number of different goals.
There is a small (and fairly static) number of ways users can legitimately complete each goal.
However, funnel steps don’t allow things like regex, so they aren’t very flexible. Also, you can only use funnels with destination-type goals. So, funnels won’t help if:
Your goals are event-based.
You have lots of ways users could reach a goal.
You have multiple teams managing the site, and it doesn’t make sense to keep track of all the ways users could reach a goal.
You should be aware that if you have a problem like internal UTMs or sessions timing out, these form funnels can mean you stop recording some conversions you should be. Seriously, make sure those problems are fixed.
The ideal approach: event-based goals
The ideal approach involves using event-based conversions rather than destination-based ones. You work with your developers so that as the users complete the form you tell GA that an event has occurred, rather than GA having to wait for a thank-you page pageview. GA then records each instance of that event as a Goal conversion.
Below is the criteria for one event-based goal conversion, if you haven’t seen them before and are struggling to picture how they’re set up. It records a conversion for this goal any time GA receives an event of the category “thank_you_page”:
The reason this is ideal is, you’ll only record a conversion when the user actually does what you want them to do. Most conversion goals based on pageviews are just us trying to guess what the user has done. That’s why you run into problems with destination-based goals, like users landing directly on your thank-you page without completing the form you wanted them to complete.
You might think it’s a bit strange to leave this “ideal” solution until so late in the post, but I’m doing so because this is often not the simplest solution. It can require the most work on the developer side, and you could be using something built into your CMS that your dev team has to edit, or even worse, you could be working with an external form solution that they have to hack their way into.
I’m bringing this solution up at this point because if you don’t already have this in place, you’ll need to convince someone to do it. Their first question may be “have you considered other options?” When you have that conversation, you can say:
We’ve made sure we’re only recording conversions on the right pages.
We’ve made sure users aren’t getting to those pages in ways we can prevent.
We’ve made sure there aren’t other issues with how we’re tracking the site.
Our conversion data is being polluted in a way we can’t prevent because we have to rely on thank-you pageviews.
We can’t filter out those conversions using Google Analytics.
The best way to make sure our data is accurate is to use events, and the most accurate events to use are ones that only occur when the user does exactly what we want them to.
If you can help me I’ll be your best friend.
An alternative to Google Analytics funnels
It could turn out that the events-based solution above is impossible. Life has its frustrations, we soldier on.
An alternative is to switch to event-based conversions anyway and use Tag Manager to handle it all yourself. Using Tag Manager and cookies, you can create a more flexible version of GA’s funnel to only send conversion events when users land on a thank-you page having visited a qualifying page. How does that work? In short:
When a user visits one of your qualifying pages, you put a cookie in their browser.
When the user loads a thank-you page, you check for the cookie, and, if it exists, you send a conversion event to Google Analytics. If it doesn’t, you don’t.
Then you clear the cookie.
That means you won’t record the following false conversions:
Users landing direct on thank-you pages.
Users accidentally clicking to thank-you pages when they haven’t visited the relevant form.
Users leaving the thank-you tab open, or bookmarking it, and clicking back to it later after their GA session expires.
The section below gets into some specific Tag Manager terminology (the most confusing being that a “Custom Event” and a “Google Analytics Event” are two different things entirely).
Some terminology to know
I’ve color coded Tag Manager terminology in blue and all Google Analytics terminology in orange, but if you find yourself getting lost, you might want to read around a bit or talk to a knowledgeable colleague or consultant.
Event: Something we send to Google Analytics to record a specific action.
Custom event: Something that happens on the web page, which we can use as part of the criteria for a Tag Manager trigger.
Trigger: A set of conditions we lay out in Tag Manager. When these conditions are all fulfilled at the same time, the trigger fires and usually activates a tag.
Tag: Something in Tag Manager that does something. This sounds vague because it could be almost anything from sending an event to Google Analytics to completely rewriting the page.
Variable: A piece of information in Tag Manager that we can easily reference in triggers, tags, or other variables.
Data layer: Structured information on the page which makes it easier to pass information to Tag manager.
How to filter conversions with Tag Manager
1. Make sure Google Tag Manager is installed on your site
It’ll need to be on every page. Google has shared a Tag Manager quick-start guide if you need further guidance.
If you’re switching from standard GA code to Tag Manager, make sure you don’t include both GA and Tag Manager, or you’ll double-count.
2. Tell Tag Manager every time a thank-you page is loaded
We’ll assume your thank-you pages are all the same type of page, so you can reasonably say to your dev team, “please make this change to all of our thank you pages”. Ask them to add something like the script below.
Example script <script> window.dataLayer.push({    "event": "conversion" }); </script>  
If you need to test this process before getting the devs involved, you can try adding the code yourself by pasting it into the console using Chrome DevTools.
When the page loads, that script will add information to the data layer. Tag Manager will detect the change, and you can use it as one of the conditions for a trigger. In this case, Tag Manager would detect a Custom Event called conversion as this data is added. We’ll come back to that.
3. Tell Tag Manager every time a qualifying page is loaded
We’ll also assume there are some similarities between your qualifying pages. For one thing, they’ll probably all have a form on them. You can coordinate with your dev team to automatically add/activate a script any time one of those forms is added.
Example script <script> window.dataLayer.push({  "event": "qualifying" }); </script>
In this case, you’d see a Custom Event called qualifying. Again, you can test this by pasting directly into Console.
4. Whenever a user lands on a qualifying page, set a cookie
You’ll use your “qualifying” Custom Event as the criteria for a trigger. Below is a screenshot of the trigger setup:
Then you’ll create a tag which will be activated by that trigger. The tag will add some content to the page, in this case adding JavaScript (even though the tag type specifies HTML). The JavaScript will run as soon as it’s added and set a cookie for the user, that way you can pass information from one page to another.
Example script <script> // Get time 30 minutes from now (this is because the default GA session timeout // is half an hour and we want our cookie timeout to match) var dt = new Date(); dt.setHours( dt.getHours() + 0.5 );
// Set a cookie called ‘qualified’ with the value being ‘true’ which expires in 30 minutes document.cookie = "qualified=true; path=/; expires="+dt; </script>
5. Get the cookie value
Use a Tag Manager variable to make sure you’re detecting the value of the cookie, which will give you the current value of your “qualified” cookie each time you check.
6. Determine whether you should filter the conversion
In step two, you created a dataLayer event that will occur on all of your final conversion pages.
Now you create a trigger which fires on your “conversion” event.
Then create a tag which is activated by that trigger, and creates another Custom Event.
Below is the custom HTML to add. It checks if your qualifying cookie is set to “true”, which shows the user has already visited a qualifying page this session. If it is true, you create another Custom Event called “create_filtered_conversion”. If it’s false, you don’t. Either way, delete the cookie by setting its expiry time to be far in the past.
Example script <script> // When we are about to fire a conversion - check if we should. // If we should - create an event that will trigger the conversion // otherwise, don’t. Either way - clear the cookie
// Get variables var isQualified =
// Check if the conversion is qualified if (isQualified === "true"){   // If the user has a qualifying cookie   window.dataLayer.push({   "event": "conversion_confirmed",   }); } else {   // Do nothing if we have determined the conversion shouldn't fire   "" }
// Set cookie expiry in the past to clear it document.cookie = "qualified=false; path=/; expires=Thu, 01 Jan 1970 00:00:00"; </script>
7. Send event to GA
First you create a trigger which is waiting for that “conversion_confirmed” event.
Then you create a tag, activated by the trigger above, which sends the relevant event to GA. The specifics of the event sent to GA can be whatever you want, you just need to make sure they match the criteria of your goal in GA.

8. Don’t switch off your old conversions straight away
One nice thing about this is you can run it alongside your existing conversion tracking to see how often conversions are being filtered out. Keep your old conversion setup running for a while (how long depends on how often you get conversions).
Watch the two numbers and check if you’re filtering out loads of conversions. This check will help you spot mistakes in either the old setup or the new one.
Let me know what you think
Google Analytics will never be a perfect record of everything on your website, but these checks and processes should help you weed out some of the ways it can mislead you.
What do you think? What GA improvements do you think people have been missing? Let me know in the comments or on Twitter @robinlord8.
Sign up for The Moz Top 10, a semimonthly mailer updating you on the top ten hottest pieces of SEO news, tips, and rad links uncovered by the Moz team. Think of it as your exclusive digest of stuff you don't have time to hunt down but want to read!
0 notes
lakelandseo · 3 years
Text
Avoiding False Conversions in Google Analytics
Posted by R0bin_L0rd
Preface
The first half of this post is a quick rundown of some of the standard ways in which your conversions could be going awry.
The second half of this post — everything after “How to filter conversions with Tag Manager” is an advanced way of intelligently filtering conversions using Tag Manager and cookies.
If you’re confident you’ve already covered your bases, feel free just to skip to the advanced section, I just feel it’s important to go through some of the basic stuff before diving into more complex solutions.
Avoiding false conversions
Aside from failing to record important data, one of the best ways to screw up your analytics is to record the wrong thing and lump it in with all the times you’ve recorded the right thing.
For example: if you’re counting conversions when you shouldn’t be, that can screw up automated ad bidding, how much you value individual channels, or even how well you think your business is doing. For this post, we’ll be referring to this issue as “false conversions”.
There are a huge number of ways you can track conversions in Google Analytics, and a huge number of ways to screw it up. This post is going to focus on some of the main ways you can mess up conversions when you’re basing them on users completing a form and then landing on a thank-you page.
We’ll cover:
Some useful tools
Things to check — how might users be accidentally converting?
How to protect destination-based goals from false conversions
An ideal event-based goal approach
How to protect event-based goals from false conversions
Useful tools
The tools below will help you with some of the checks in this post.
Chrome DevTools
F12 will open Chrome DevTools (you may need to press the “function” key depending on your keyboard). You can test JavaScript in “Console”, and view active cookies in “Application”.
Google Tag Manager preview
Google Tag Manager has a new preview which will show you what happens on a series of pages over time.
Adswerve dataLayer Inspector
This plugin summarizes dataLayer information in Chrome Console.
Analytics Tracking Monitor plugin
I’ve found this plugin really useful for checking what information is being sent to GA. One nice feature is being able to block hits from actually being sent to GA while recording what would be sent.
Tag Assistant
The Chrome Tag Assistant plugin will show you what Tag Manager tags are present on the page. If you click to record the session, it’ll also give you a breakdown of everything that’s happened on each page. That said — I don’t tend to rely on the recordings as much if I have Tag Manager access, because a lot of the useful information is covered between the new GTM preview and the tracking monitor plugin.
Tag Mapper
I created a free Tag Mapper tool to make it easier to see what impact Tag Manager changes might have. If you’re planning on changing something in your GTM account, you can see what else might be impacted. Likewise, if you’ve noticed that something is broken, it can help you find the root cause.
Things to check
It can be tempting to leap straight to a catch-all solution, but if you’re recording conversions when you shouldn’t be, that could be because your website visitors are doing things they shouldn’t be.
Let’s start with a quick rundown of checks you should do to make sure you’re not making the numbers look right by just ignoring problems on your site.
1. Are you only recording conversions on thank-you pages?
To check if you’re recording conversions on pages you shouldn’t be (like, every page on your site or something) have a quick look at the Reverse Goal Path report in Google Analytics:
Conversions > Goals > Reverse Goal Path.
The first column on the left should show you where your goal conversions are taking place, unless you’re doing something unusual. If you’re seeing a bunch of pages in that column which you don’t expect, that’s a sign you need to change your criteria for conversions.
One thing to bear in mind here: if you’re recording conversions based on events rather than pageviews, and you’re seeing the wrong page appearing in that left-hand column, make sure your conversion event only ever fires after your pageview.
2. Are you linking to conversion pages in other ways besides form completions?
If you’re using any goals based on a user loading a specific page (like a thank-you page), and you know you’re only recording conversions on thank-you pages, another way you could be screwing things up is accidentally linking to those thank-you pages. If a user can click on the wrong link and end up on a conversion page, you need to fix that.
One way to check for this is using a tool like Screaming Frog to crawl the site and just see if your conversion pages appear. If they appear at all, you know that’s probably a problem. To find out how to fix the problem, you can select the offending pages and check the “Inlinks” panel, which will give you a list of where you’re linking to them.
3. Are users landing directly on thank-you pages?
A quick way to check if users are landing on your thank-you pages is to use segments. If you create a segment where the landing page is your thank-you page, you can get an idea of how often Google Analytics thinks users are landing on your conversion page.
Below, you can see a screenshot of the segment interface. I’ve set it to include any session where the first interaction was a user landing on a thank-you landing page. As you can see, that was the case for 339 sessions on this site:
Once you see how often users are landing on your thank-you pages, you can pinpoint the sources which are bringing those users to the site.
Below, I’ve applied a “lands on thank-you page” segment to the Source/Medium report, and it looks like we’re getting a bunch of direct sessions, but also some CPC sessions, and organic sessions elsewhere, too:
An important thing to bear in mind here is that this is based on what Google Analytics thinks is happening. It doesn’t necessarily mean users are landing on these pages directly from adverts. In fact, in this example, we know this isn’t always the case, and sometimes it’s a symptom of our tracking code being broken or confused in another way. Even so, it gives us some things to investigate.
For example:
Do we have adverts or other activity pointing straight to conversion pages?
Are our conversion pages indexed in Google?
Do we have a page in the middle of our conversion flow that isn’t being tracked?
Is our tracking code broken, or are users doing things on-site which would confuse GA?
3.1 Do you have adverts or other activity pointing straight to conversion pages?
I won’t be able to walk you through all of this, but all advertising platforms should allow you to check active landing pages. It’s also important to make sure that you don’t have any affiliates linking directly to conversion pages — either accidentally or maliciously — as you could be paying them a lot more than they deserve.
It may be harder to check non-paid links, like social media activity. That said, it’s worth spending the time checking. If you find you’re linking to these conversion pages by accident, you can work with relevant teams to put policies in place for that in future.
3.2 Are your conversion pages indexed in Google?
Google can be a frequent cause of conversion page issues. It’s a ravenous crawler. It’ll follow links inside and outside of your site, and if there’s a machine-crawlable link to your thank-you page, it’ll probably find it.
A quick way to check if Google has saved your thank-you pages (and might be sending users straight to them) is to search for the pages in Google.
Using “site:” filters Google results to just pages on your site. Using “inurl:” filters results to just pages that contain a specific string.
Below is an example of a check we did for one of our clients. We found that they had a lot of “thank-you” pages in the index (over 600). Some of those pages were fine, but it highlighted a number of conversion pages for us to deal with:
3.3 Is your tracking code broken, or are users doing things on-site which would confuse GA?
We don’t have time to go through all the things that could go wrong here. Some things to check are:
Are you missing tracking code on some pages? Perhaps you’re failing to record the user before they land on the thank-you page.
Do you have different versions of Google Analytics on different pages? This can, again, cause confused or split sessions.
Are you including UTM parameters on any internal links? Any website crawler should help you find this.
Do you have the wrong timezone set in GA? Sessions can’t cross “midnight” — if they do, GA will split them into two separate sessions.
Are you including important information on the thank-you page that could cause users to bookmark the page, or try to come back to it later? One solution here is to include pretty much nothing visitor-specific on the thank-you page, and assure them that you’ll email them details. It’s worth testing this to make sure it doesn’t hurt visitor confidence.
Do you have any forms, that take more than half an hour to fill out, and don’t record interactions in the meantime? You can avoid this by splitting the form into different pages and tracking when visitors fill out a form field or when they hit errors. Entirely aside from what we’re looking at in this post, but all of these things should help you make your forms more user-friendly.
Once you have all of those checked off, you can start to look at ways to improve the way you filter your conversion data.
How to protect destination-based goals from false conversions
If you have your goal type set to “Destination” in Google Analytics, that means that any time GA records a pageview for a specific page, it’ll count as a conversion.
You can make your destination goals require users to have visited other pages first by using a funnel. If you edit the goal and switch “Funnel” on, you can specify the steps leading up to the goal. This means you can make sure that you don’t record goal conversions when users land directly on your thank-you pages.
You can also use it to separate out different kinds of goal conversions. For example, if you use the same thank-you page for multiple forms, you could have one goal where the funnel involves traveling through one form page, and another goal which involves traveling through another.
This will work if you:
Have a smaller (and fairly static) number of different goals.
There is a small (and fairly static) number of ways users can legitimately complete each goal.
However, funnel steps don’t allow things like regex, so they aren’t very flexible. Also, you can only use funnels with destination-type goals. So, funnels won’t help if:
Your goals are event-based.
You have lots of ways users could reach a goal.
You have multiple teams managing the site, and it doesn’t make sense to keep track of all the ways users could reach a goal.
You should be aware that if you have a problem like internal UTMs or sessions timing out, these form funnels can mean you stop recording some conversions you should be. Seriously, make sure those problems are fixed.
The ideal approach: event-based goals
The ideal approach involves using event-based conversions rather than destination-based ones. You work with your developers so that as the users complete the form you tell GA that an event has occurred, rather than GA having to wait for a thank-you page pageview. GA then records each instance of that event as a Goal conversion.
Below is the criteria for one event-based goal conversion, if you haven’t seen them before and are struggling to picture how they’re set up. It records a conversion for this goal any time GA receives an event of the category “thank_you_page”:
The reason this is ideal is, you’ll only record a conversion when the user actually does what you want them to do. Most conversion goals based on pageviews are just us trying to guess what the user has done. That’s why you run into problems with destination-based goals, like users landing directly on your thank-you page without completing the form you wanted them to complete.
You might think it’s a bit strange to leave this “ideal” solution until so late in the post, but I’m doing so because this is often not the simplest solution. It can require the most work on the developer side, and you could be using something built into your CMS that your dev team has to edit, or even worse, you could be working with an external form solution that they have to hack their way into.
I’m bringing this solution up at this point because if you don’t already have this in place, you’ll need to convince someone to do it. Their first question may be “have you considered other options?” When you have that conversation, you can say:
We’ve made sure we’re only recording conversions on the right pages.
We’ve made sure users aren’t getting to those pages in ways we can prevent.
We’ve made sure there aren’t other issues with how we’re tracking the site.
Our conversion data is being polluted in a way we can’t prevent because we have to rely on thank-you pageviews.
We can’t filter out those conversions using Google Analytics.
The best way to make sure our data is accurate is to use events, and the most accurate events to use are ones that only occur when the user does exactly what we want them to.
If you can help me I’ll be your best friend.
An alternative to Google Analytics funnels
It could turn out that the events-based solution above is impossible. Life has its frustrations, we soldier on.
An alternative is to switch to event-based conversions anyway and use Tag Manager to handle it all yourself. Using Tag Manager and cookies, you can create a more flexible version of GA’s funnel to only send conversion events when users land on a thank-you page having visited a qualifying page. How does that work? In short:
When a user visits one of your qualifying pages, you put a cookie in their browser.
When the user loads a thank-you page, you check for the cookie, and, if it exists, you send a conversion event to Google Analytics. If it doesn’t, you don’t.
Then you clear the cookie.
That means you won’t record the following false conversions:
Users landing direct on thank-you pages.
Users accidentally clicking to thank-you pages when they haven’t visited the relevant form.
Users leaving the thank-you tab open, or bookmarking it, and clicking back to it later after their GA session expires.
The section below gets into some specific Tag Manager terminology (the most confusing being that a “Custom Event” and a “Google Analytics Event” are two different things entirely).
Some terminology to know
I’ve color coded Tag Manager terminology in blue and all Google Analytics terminology in orange, but if you find yourself getting lost, you might want to read around a bit or talk to a knowledgeable colleague or consultant.
Event: Something we send to Google Analytics to record a specific action.
Custom event: Something that happens on the web page, which we can use as part of the criteria for a Tag Manager trigger.
Trigger: A set of conditions we lay out in Tag Manager. When these conditions are all fulfilled at the same time, the trigger fires and usually activates a tag.
Tag: Something in Tag Manager that does something. This sounds vague because it could be almost anything from sending an event to Google Analytics to completely rewriting the page.
Variable: A piece of information in Tag Manager that we can easily reference in triggers, tags, or other variables.
Data layer: Structured information on the page which makes it easier to pass information to Tag manager.
How to filter conversions with Tag Manager
1. Make sure Google Tag Manager is installed on your site
It’ll need to be on every page. Google has shared a Tag Manager quick-start guide if you need further guidance.
If you’re switching from standard GA code to Tag Manager, make sure you don’t include both GA and Tag Manager, or you’ll double-count.
2. Tell Tag Manager every time a thank-you page is loaded
We’ll assume your thank-you pages are all the same type of page, so you can reasonably say to your dev team, “please make this change to all of our thank you pages”. Ask them to add something like the script below.
Example script <script> window.dataLayer.push({    "event": "conversion" }); </script>  
If you need to test this process before getting the devs involved, you can try adding the code yourself by pasting it into the console using Chrome DevTools.
When the page loads, that script will add information to the data layer. Tag Manager will detect the change, and you can use it as one of the conditions for a trigger. In this case, Tag Manager would detect a Custom Event called conversion as this data is added. We’ll come back to that.
3. Tell Tag Manager every time a qualifying page is loaded
We’ll also assume there are some similarities between your qualifying pages. For one thing, they’ll probably all have a form on them. You can coordinate with your dev team to automatically add/activate a script any time one of those forms is added.
Example script <script> window.dataLayer.push({  "event": "qualifying" }); </script>
In this case, you’d see a Custom Event called qualifying. Again, you can test this by pasting directly into Console.
4. Whenever a user lands on a qualifying page, set a cookie
You’ll use your “qualifying” Custom Event as the criteria for a trigger. Below is a screenshot of the trigger setup:
Then you’ll create a tag which will be activated by that trigger. The tag will add some content to the page, in this case adding JavaScript (even though the tag type specifies HTML). The JavaScript will run as soon as it’s added and set a cookie for the user, that way you can pass information from one page to another.
Example script <script> // Get time 30 minutes from now (this is because the default GA session timeout // is half an hour and we want our cookie timeout to match) var dt = new Date(); dt.setHours( dt.getHours() + 0.5 );
// Set a cookie called ‘qualified’ with the value being ‘true’ which expires in 30 minutes document.cookie = "qualified=true; path=/; expires="+dt; </script>
5. Get the cookie value
Use a Tag Manager variable to make sure you’re detecting the value of the cookie, which will give you the current value of your “qualified” cookie each time you check.
6. Determine whether you should filter the conversion
In step two, you created a dataLayer event that will occur on all of your final conversion pages.
Now you create a trigger which fires on your “conversion” event.
Then create a tag which is activated by that trigger, and creates another Custom Event.
Below is the custom HTML to add. It checks if your qualifying cookie is set to “true”, which shows the user has already visited a qualifying page this session. If it is true, you create another Custom Event called “create_filtered_conversion”. If it’s false, you don’t. Either way, delete the cookie by setting its expiry time to be far in the past.
Example script <script> // When we are about to fire a conversion - check if we should. // If we should - create an event that will trigger the conversion // otherwise, don’t. Either way - clear the cookie
// Get variables var isQualified =
// Check if the conversion is qualified if (isQualified === "true"){   // If the user has a qualifying cookie   window.dataLayer.push({   "event": "conversion_confirmed",   }); } else {   // Do nothing if we have determined the conversion shouldn't fire   "" }
// Set cookie expiry in the past to clear it document.cookie = "qualified=false; path=/; expires=Thu, 01 Jan 1970 00:00:00"; </script>
7. Send event to GA
First you create a trigger which is waiting for that “conversion_confirmed” event.
Then you create a tag, activated by the trigger above, which sends the relevant event to GA. The specifics of the event sent to GA can be whatever you want, you just need to make sure they match the criteria of your goal in GA.

8. Don’t switch off your old conversions straight away
One nice thing about this is you can run it alongside your existing conversion tracking to see how often conversions are being filtered out. Keep your old conversion setup running for a while (how long depends on how often you get conversions).
Watch the two numbers and check if you’re filtering out loads of conversions. This check will help you spot mistakes in either the old setup or the new one.
Let me know what you think
Google Analytics will never be a perfect record of everything on your website, but these checks and processes should help you weed out some of the ways it can mislead you.
What do you think? What GA improvements do you think people have been missing? Let me know in the comments or on Twitter @robinlord8.
Sign up for The Moz Top 10, a semimonthly mailer updating you on the top ten hottest pieces of SEO news, tips, and rad links uncovered by the Moz team. Think of it as your exclusive digest of stuff you don't have time to hunt down but want to read!
0 notes
epackingvietnam · 3 years
Text
Avoiding False Conversions in Google Analytics
Posted by R0bin_L0rd
Preface
The first half of this post is a quick rundown of some of the standard ways in which your conversions could be going awry.
The second half of this post — everything after “How to filter conversions with Tag Manager” is an advanced way of intelligently filtering conversions using Tag Manager and cookies.
If you’re confident you’ve already covered your bases, feel free just to skip to the advanced section, I just feel it’s important to go through some of the basic stuff before diving into more complex solutions.
Avoiding false conversions
Aside from failing to record important data, one of the best ways to screw up your analytics is to record the wrong thing and lump it in with all the times you’ve recorded the right thing.
For example: if you’re counting conversions when you shouldn’t be, that can screw up automated ad bidding, how much you value individual channels, or even how well you think your business is doing. For this post, we’ll be referring to this issue as “false conversions”.
There are a huge number of ways you can track conversions in Google Analytics, and a huge number of ways to screw it up. This post is going to focus on some of the main ways you can mess up conversions when you’re basing them on users completing a form and then landing on a thank-you page.
We’ll cover:
Some useful tools
Things to check — how might users be accidentally converting?
How to protect destination-based goals from false conversions
An ideal event-based goal approach
How to protect event-based goals from false conversions
Useful tools
The tools below will help you with some of the checks in this post.
Chrome DevTools
F12 will open Chrome DevTools (you may need to press the “function” key depending on your keyboard). You can test JavaScript in “Console”, and view active cookies in “Application”.
Google Tag Manager preview
Google Tag Manager has a new preview which will show you what happens on a series of pages over time.
Adswerve dataLayer Inspector
This plugin summarizes dataLayer information in Chrome Console.
Analytics Tracking Monitor plugin
I’ve found this plugin really useful for checking what information is being sent to GA. One nice feature is being able to block hits from actually being sent to GA while recording what would be sent.
Tag Assistant
The Chrome Tag Assistant plugin will show you what Tag Manager tags are present on the page. If you click to record the session, it’ll also give you a breakdown of everything that’s happened on each page. That said — I don’t tend to rely on the recordings as much if I have Tag Manager access, because a lot of the useful information is covered between the new GTM preview and the tracking monitor plugin.
Tag Mapper
I created a free Tag Mapper tool to make it easier to see what impact Tag Manager changes might have. If you’re planning on changing something in your GTM account, you can see what else might be impacted. Likewise, if you’ve noticed that something is broken, it can help you find the root cause.
Things to check
It can be tempting to leap straight to a catch-all solution, but if you’re recording conversions when you shouldn’t be, that could be because your website visitors are doing things they shouldn’t be.
Let’s start with a quick rundown of checks you should do to make sure you’re not making the numbers look right by just ignoring problems on your site.
1. Are you only recording conversions on thank-you pages?
To check if you’re recording conversions on pages you shouldn’t be (like, every page on your site or something) have a quick look at the Reverse Goal Path report in Google Analytics:
Conversions > Goals > Reverse Goal Path.
The first column on the left should show you where your goal conversions are taking place, unless you’re doing something unusual. If you’re seeing a bunch of pages in that column which you don’t expect, that’s a sign you need to change your criteria for conversions.
One thing to bear in mind here: if you’re recording conversions based on events rather than pageviews, and you’re seeing the wrong page appearing in that left-hand column, make sure your conversion event only ever fires after your pageview.
2. Are you linking to conversion pages in other ways besides form completions?
If you’re using any goals based on a user loading a specific page (like a thank-you page), and you know you’re only recording conversions on thank-you pages, another way you could be screwing things up is accidentally linking to those thank-you pages. If a user can click on the wrong link and end up on a conversion page, you need to fix that.
One way to check for this is using a tool like Screaming Frog to crawl the site and just see if your conversion pages appear. If they appear at all, you know that’s probably a problem. To find out how to fix the problem, you can select the offending pages and check the “Inlinks” panel, which will give you a list of where you’re linking to them.
3. Are users landing directly on thank-you pages?
A quick way to check if users are landing on your thank-you pages is to use segments. If you create a segment where the landing page is your thank-you page, you can get an idea of how often Google Analytics thinks users are landing on your conversion page.
Below, you can see a screenshot of the segment interface. I’ve set it to include any session where the first interaction was a user landing on a thank-you landing page. As you can see, that was the case for 339 sessions on this site:
Once you see how often users are landing on your thank-you pages, you can pinpoint the sources which are bringing those users to the site.
Below, I’ve applied a “lands on thank-you page” segment to the Source/Medium report, and it looks like we’re getting a bunch of direct sessions, but also some CPC sessions, and organic sessions elsewhere, too:
An important thing to bear in mind here is that this is based on what Google Analytics thinks is happening. It doesn’t necessarily mean users are landing on these pages directly from adverts. In fact, in this example, we know this isn’t always the case, and sometimes it’s a symptom of our tracking code being broken or confused in another way. Even so, it gives us some things to investigate.
For example:
Do we have adverts or other activity pointing straight to conversion pages?
Are our conversion pages indexed in Google?
Do we have a page in the middle of our conversion flow that isn’t being tracked?
Is our tracking code broken, or are users doing things on-site which would confuse GA?
3.1 Do you have adverts or other activity pointing straight to conversion pages?
I won’t be able to walk you through all of this, but all advertising platforms should allow you to check active landing pages. It’s also important to make sure that you don’t have any affiliates linking directly to conversion pages — either accidentally or maliciously — as you could be paying them a lot more than they deserve.
It may be harder to check non-paid links, like social media activity. That said, it’s worth spending the time checking. If you find you’re linking to these conversion pages by accident, you can work with relevant teams to put policies in place for that in future.
3.2 Are your conversion pages indexed in Google?
Google can be a frequent cause of conversion page issues. It’s a ravenous crawler. It’ll follow links inside and outside of your site, and if there’s a machine-crawlable link to your thank-you page, it’ll probably find it.
A quick way to check if Google has saved your thank-you pages (and might be sending users straight to them) is to search for the pages in Google.
Using “site:” filters Google results to just pages on your site. Using “inurl:” filters results to just pages that contain a specific string.
Below is an example of a check we did for one of our clients. We found that they had a lot of “thank-you” pages in the index (over 600). Some of those pages were fine, but it highlighted a number of conversion pages for us to deal with:
3.3 Is your tracking code broken, or are users doing things on-site which would confuse GA?
We don’t have time to go through all the things that could go wrong here. Some things to check are:
Are you missing tracking code on some pages? Perhaps you’re failing to record the user before they land on the thank-you page.
Do you have different versions of Google Analytics on different pages? This can, again, cause confused or split sessions.
Are you including UTM parameters on any internal links? Any website crawler should help you find this.
Do you have the wrong timezone set in GA? Sessions can’t cross “midnight” — if they do, GA will split them into two separate sessions.
Are you including important information on the thank-you page that could cause users to bookmark the page, or try to come back to it later? One solution here is to include pretty much nothing visitor-specific on the thank-you page, and assure them that you’ll email them details. It’s worth testing this to make sure it doesn’t hurt visitor confidence.
Do you have any forms, that take more than half an hour to fill out, and don’t record interactions in the meantime? You can avoid this by splitting the form into different pages and tracking when visitors fill out a form field or when they hit errors. Entirely aside from what we’re looking at in this post, but all of these things should help you make your forms more user-friendly.
Once you have all of those checked off, you can start to look at ways to improve the way you filter your conversion data.
How to protect destination-based goals from false conversions
If you have your goal type set to “Destination” in Google Analytics, that means that any time GA records a pageview for a specific page, it’ll count as a conversion.
You can make your destination goals require users to have visited other pages first by using a funnel. If you edit the goal and switch “Funnel” on, you can specify the steps leading up to the goal. This means you can make sure that you don’t record goal conversions when users land directly on your thank-you pages.
You can also use it to separate out different kinds of goal conversions. For example, if you use the same thank-you page for multiple forms, you could have one goal where the funnel involves traveling through one form page, and another goal which involves traveling through another.
This will work if you:
Have a smaller (and fairly static) number of different goals.
There is a small (and fairly static) number of ways users can legitimately complete each goal.
However, funnel steps don’t allow things like regex, so they aren’t very flexible. Also, you can only use funnels with destination-type goals. So, funnels won’t help if:
Your goals are event-based.
You have lots of ways users could reach a goal.
You have multiple teams managing the site, and it doesn’t make sense to keep track of all the ways users could reach a goal.
You should be aware that if you have a problem like internal UTMs or sessions timing out, these form funnels can mean you stop recording some conversions you should be. Seriously, make sure those problems are fixed.
The ideal approach: event-based goals
The ideal approach involves using event-based conversions rather than destination-based ones. You work with your developers so that as the users complete the form you tell GA that an event has occurred, rather than GA having to wait for a thank-you page pageview. GA then records each instance of that event as a Goal conversion.
Below is the criteria for one event-based goal conversion, if you haven’t seen them before and are struggling to picture how they’re set up. It records a conversion for this goal any time GA receives an event of the category “thank_you_page”:
The reason this is ideal is, you’ll only record a conversion when the user actually does what you want them to do. Most conversion goals based on pageviews are just us trying to guess what the user has done. That’s why you run into problems with destination-based goals, like users landing directly on your thank-you page without completing the form you wanted them to complete.
You might think it’s a bit strange to leave this “ideal” solution until so late in the post, but I’m doing so because this is often not the simplest solution. It can require the most work on the developer side, and you could be using something built into your CMS that your dev team has to edit, or even worse, you could be working with an external form solution that they have to hack their way into.
I’m bringing this solution up at this point because if you don’t already have this in place, you’ll need to convince someone to do it. Their first question may be “have you considered other options?” When you have that conversation, you can say:
We’ve made sure we’re only recording conversions on the right pages.
We’ve made sure users aren’t getting to those pages in ways we can prevent.
We’ve made sure there aren’t other issues with how we’re tracking the site.
Our conversion data is being polluted in a way we can’t prevent because we have to rely on thank-you pageviews.
We can’t filter out those conversions using Google Analytics.
The best way to make sure our data is accurate is to use events, and the most accurate events to use are ones that only occur when the user does exactly what we want them to.
If you can help me I’ll be your best friend.
An alternative to Google Analytics funnels
It could turn out that the events-based solution above is impossible. Life has its frustrations, we soldier on.
An alternative is to switch to event-based conversions anyway and use Tag Manager to handle it all yourself. Using Tag Manager and cookies, you can create a more flexible version of GA’s funnel to only send conversion events when users land on a thank-you page having visited a qualifying page. How does that work? In short:
When a user visits one of your qualifying pages, you put a cookie in their browser.
When the user loads a thank-you page, you check for the cookie, and, if it exists, you send a conversion event to Google Analytics. If it doesn’t, you don’t.
Then you clear the cookie.
That means you won’t record the following false conversions:
Users landing direct on thank-you pages.
Users accidentally clicking to thank-you pages when they haven’t visited the relevant form.
Users leaving the thank-you tab open, or bookmarking it, and clicking back to it later after their GA session expires.
The section below gets into some specific Tag Manager terminology (the most confusing being that a “Custom Event” and a “Google Analytics Event” are two different things entirely).
Some terminology to know
I’ve color coded Tag Manager terminology in blue and all Google Analytics terminology in orange, but if you find yourself getting lost, you might want to read around a bit or talk to a knowledgeable colleague or consultant.
Event: Something we send to Google Analytics to record a specific action.
Custom event: Something that happens on the web page, which we can use as part of the criteria for a Tag Manager trigger.
Trigger: A set of conditions we lay out in Tag Manager. When these conditions are all fulfilled at the same time, the trigger fires and usually activates a tag.
Tag: Something in Tag Manager that does something. This sounds vague because it could be almost anything from sending an event to Google Analytics to completely rewriting the page.
Variable: A piece of information in Tag Manager that we can easily reference in triggers, tags, or other variables.
Data layer: Structured information on the page which makes it easier to pass information to Tag manager.
How to filter conversions with Tag Manager
1. Make sure Google Tag Manager is installed on your site
It’ll need to be on every page. Google has shared a Tag Manager quick-start guide if you need further guidance.
If you’re switching from standard GA code to Tag Manager, make sure you don’t include both GA and Tag Manager, or you’ll double-count.
2. Tell Tag Manager every time a thank-you page is loaded
We’ll assume your thank-you pages are all the same type of page, so you can reasonably say to your dev team, “please make this change to all of our thank you pages”. Ask them to add something like the script below.
Example script <script> window.dataLayer.push({    "event": "conversion" }); </script>  
If you need to test this process before getting the devs involved, you can try adding the code yourself by pasting it into the console using Chrome DevTools.
When the page loads, that script will add information to the data layer. Tag Manager will detect the change, and you can use it as one of the conditions for a trigger. In this case, Tag Manager would detect a Custom Event called conversion as this data is added. We’ll come back to that.
3. Tell Tag Manager every time a qualifying page is loaded
We’ll also assume there are some similarities between your qualifying pages. For one thing, they’ll probably all have a form on them. You can coordinate with your dev team to automatically add/activate a script any time one of those forms is added.
Example script <script> window.dataLayer.push({  "event": "qualifying" }); </script>
In this case, you’d see a Custom Event called qualifying. Again, you can test this by pasting directly into Console.
4. Whenever a user lands on a qualifying page, set a cookie
You’ll use your “qualifying” Custom Event as the criteria for a trigger. Below is a screenshot of the trigger setup:
Then you’ll create a tag which will be activated by that trigger. The tag will add some content to the page, in this case adding JavaScript (even though the tag type specifies HTML). The JavaScript will run as soon as it’s added and set a cookie for the user, that way you can pass information from one page to another.
Example script <script> // Get time 30 minutes from now (this is because the default GA session timeout // is half an hour and we want our cookie timeout to match) var dt = new Date(); dt.setHours( dt.getHours() + 0.5 );
// Set a cookie called ‘qualified’ with the value being ‘true’ which expires in 30 minutes document.cookie = "qualified=true; path=/; expires="+dt; </script>
5. Get the cookie value
Use a Tag Manager variable to make sure you’re detecting the value of the cookie, which will give you the current value of your “qualified” cookie each time you check.
6. Determine whether you should filter the conversion
In step two, you created a dataLayer event that will occur on all of your final conversion pages.
Now you create a trigger which fires on your “conversion” event.
Then create a tag which is activated by that trigger, and creates another Custom Event.
Below is the custom HTML to add. It checks if your qualifying cookie is set to “true”, which shows the user has already visited a qualifying page this session. If it is true, you create another Custom Event called “create_filtered_conversion”. If it’s false, you don’t. Either way, delete the cookie by setting its expiry time to be far in the past.
Example script <script> // When we are about to fire a conversion - check if we should. // If we should - create an event that will trigger the conversion // otherwise, don’t. Either way - clear the cookie
// Get variables var isQualified =
// Check if the conversion is qualified if (isQualified === "true"){   // If the user has a qualifying cookie   window.dataLayer.push({   "event": "conversion_confirmed",   }); } else {   // Do nothing if we have determined the conversion shouldn't fire   "" }
// Set cookie expiry in the past to clear it document.cookie = "qualified=false; path=/; expires=Thu, 01 Jan 1970 00:00:00"; </script>
7. Send event to GA
First you create a trigger which is waiting for that “conversion_confirmed” event.
Then you create a tag, activated by the trigger above, which sends the relevant event to GA. The specifics of the event sent to GA can be whatever you want, you just need to make sure they match the criteria of your goal in GA.

8. Don’t switch off your old conversions straight away
One nice thing about this is you can run it alongside your existing conversion tracking to see how often conversions are being filtered out. Keep your old conversion setup running for a while (how long depends on how often you get conversions).
Watch the two numbers and check if you’re filtering out loads of conversions. This check will help you spot mistakes in either the old setup or the new one.
Let me know what you think
Google Analytics will never be a perfect record of everything on your website, but these checks and processes should help you weed out some of the ways it can mislead you.
What do you think? What GA improvements do you think people have been missing? Let me know in the comments or on Twitter @robinlord8.
Sign up for The Moz Top 10, a semimonthly mailer updating you on the top ten hottest pieces of SEO news, tips, and rad links uncovered by the Moz team. Think of it as your exclusive digest of stuff you don't have time to hunt down but want to read!
#túi_giấy_epacking_việt_nam #túi_giấy_epacking #in_túi_giấy_giá_rẻ #in_túi_giấy #epackingvietnam #tuigiayepacking
0 notes
bfxenon · 3 years
Text
Avoiding False Conversions in Google Analytics
Posted by R0bin_L0rd
Preface
The first half of this post is a quick rundown of some of the standard ways in which your conversions could be going awry.
The second half of this post — everything after “How to filter conversions with Tag Manager” is an advanced way of intelligently filtering conversions using Tag Manager and cookies.
If you’re confident you’ve already covered your bases, feel free just to skip to the advanced section, I just feel it’s important to go through some of the basic stuff before diving into more complex solutions.
Avoiding false conversions
Aside from failing to record important data, one of the best ways to screw up your analytics is to record the wrong thing and lump it in with all the times you’ve recorded the right thing.
For example: if you’re counting conversions when you shouldn’t be, that can screw up automated ad bidding, how much you value individual channels, or even how well you think your business is doing. For this post, we’ll be referring to this issue as “false conversions”.
There are a huge number of ways you can track conversions in Google Analytics, and a huge number of ways to screw it up. This post is going to focus on some of the main ways you can mess up conversions when you’re basing them on users completing a form and then landing on a thank-you page.
We’ll cover:
Some useful tools
Things to check — how might users be accidentally converting?
How to protect destination-based goals from false conversions
An ideal event-based goal approach
How to protect event-based goals from false conversions
Useful tools
The tools below will help you with some of the checks in this post.
Chrome DevTools
F12 will open Chrome DevTools (you may need to press the “function” key depending on your keyboard). You can test JavaScript in “Console”, and view active cookies in “Application”.
Google Tag Manager preview
Google Tag Manager has a new preview which will show you what happens on a series of pages over time.
Adswerve dataLayer Inspector
This plugin summarizes dataLayer information in Chrome Console.
Analytics Tracking Monitor plugin
I’ve found this plugin really useful for checking what information is being sent to GA. One nice feature is being able to block hits from actually being sent to GA while recording what would be sent.
Tag Assistant
The Chrome Tag Assistant plugin will show you what Tag Manager tags are present on the page. If you click to record the session, it’ll also give you a breakdown of everything that’s happened on each page. That said — I don’t tend to rely on the recordings as much if I have Tag Manager access, because a lot of the useful information is covered between the new GTM preview and the tracking monitor plugin.
Tag Mapper
I created a free Tag Mapper tool to make it easier to see what impact Tag Manager changes might have. If you’re planning on changing something in your GTM account, you can see what else might be impacted. Likewise, if you’ve noticed that something is broken, it can help you find the root cause.
Things to check
It can be tempting to leap straight to a catch-all solution, but if you’re recording conversions when you shouldn’t be, that could be because your website visitors are doing things they shouldn’t be.
Let’s start with a quick rundown of checks you should do to make sure you’re not making the numbers look right by just ignoring problems on your site.
1. Are you only recording conversions on thank-you pages?
To check if you’re recording conversions on pages you shouldn’t be (like, every page on your site or something) have a quick look at the Reverse Goal Path report in Google Analytics:
Conversions > Goals > Reverse Goal Path.
The first column on the left should show you where your goal conversions are taking place, unless you’re doing something unusual. If you’re seeing a bunch of pages in that column which you don’t expect, that’s a sign you need to change your criteria for conversions.
One thing to bear in mind here: if you’re recording conversions based on events rather than pageviews, and you’re seeing the wrong page appearing in that left-hand column, make sure your conversion event only ever fires after your pageview.
2. Are you linking to conversion pages in other ways besides form completions?
If you’re using any goals based on a user loading a specific page (like a thank-you page), and you know you’re only recording conversions on thank-you pages, another way you could be screwing things up is accidentally linking to those thank-you pages. If a user can click on the wrong link and end up on a conversion page, you need to fix that.
One way to check for this is using a tool like Screaming Frog to crawl the site and just see if your conversion pages appear. If they appear at all, you know that’s probably a problem. To find out how to fix the problem, you can select the offending pages and check the “Inlinks” panel, which will give you a list of where you’re linking to them.
3. Are users landing directly on thank-you pages?
A quick way to check if users are landing on your thank-you pages is to use segments. If you create a segment where the landing page is your thank-you page, you can get an idea of how often Google Analytics thinks users are landing on your conversion page.
Below, you can see a screenshot of the segment interface. I’ve set it to include any session where the first interaction was a user landing on a thank-you landing page. As you can see, that was the case for 339 sessions on this site:
Once you see how often users are landing on your thank-you pages, you can pinpoint the sources which are bringing those users to the site.
Below, I’ve applied a “lands on thank-you page” segment to the Source/Medium report, and it looks like we’re getting a bunch of direct sessions, but also some CPC sessions, and organic sessions elsewhere, too:
An important thing to bear in mind here is that this is based on what Google Analytics thinks is happening. It doesn’t necessarily mean users are landing on these pages directly from adverts. In fact, in this example, we know this isn’t always the case, and sometimes it’s a symptom of our tracking code being broken or confused in another way. Even so, it gives us some things to investigate.
For example:
Do we have adverts or other activity pointing straight to conversion pages?
Are our conversion pages indexed in Google?
Do we have a page in the middle of our conversion flow that isn’t being tracked?
Is our tracking code broken, or are users doing things on-site which would confuse GA?
3.1 Do you have adverts or other activity pointing straight to conversion pages?
I won’t be able to walk you through all of this, but all advertising platforms should allow you to check active landing pages. It’s also important to make sure that you don’t have any affiliates linking directly to conversion pages — either accidentally or maliciously — as you could be paying them a lot more than they deserve.
It may be harder to check non-paid links, like social media activity. That said, it’s worth spending the time checking. If you find you’re linking to these conversion pages by accident, you can work with relevant teams to put policies in place for that in future.
3.2 Are your conversion pages indexed in Google?
Google can be a frequent cause of conversion page issues. It’s a ravenous crawler. It’ll follow links inside and outside of your site, and if there’s a machine-crawlable link to your thank-you page, it’ll probably find it.
A quick way to check if Google has saved your thank-you pages (and might be sending users straight to them) is to search for the pages in Google.
Using “site:” filters Google results to just pages on your site. Using “inurl:” filters results to just pages that contain a specific string.
Below is an example of a check we did for one of our clients. We found that they had a lot of “thank-you” pages in the index (over 600). Some of those pages were fine, but it highlighted a number of conversion pages for us to deal with:
3.3 Is your tracking code broken, or are users doing things on-site which would confuse GA?
We don’t have time to go through all the things that could go wrong here. Some things to check are:
Are you missing tracking code on some pages? Perhaps you’re failing to record the user before they land on the thank-you page.
Do you have different versions of Google Analytics on different pages? This can, again, cause confused or split sessions.
Are you including UTM parameters on any internal links? Any website crawler should help you find this.
Do you have the wrong timezone set in GA? Sessions can’t cross “midnight” — if they do, GA will split them into two separate sessions.
Are you including important information on the thank-you page that could cause users to bookmark the page, or try to come back to it later? One solution here is to include pretty much nothing visitor-specific on the thank-you page, and assure them that you’ll email them details. It’s worth testing this to make sure it doesn’t hurt visitor confidence.
Do you have any forms, that take more than half an hour to fill out, and don’t record interactions in the meantime? You can avoid this by splitting the form into different pages and tracking when visitors fill out a form field or when they hit errors. Entirely aside from what we’re looking at in this post, but all of these things should help you make your forms more user-friendly.
Once you have all of those checked off, you can start to look at ways to improve the way you filter your conversion data.
How to protect destination-based goals from false conversions
If you have your goal type set to “Destination” in Google Analytics, that means that any time GA records a pageview for a specific page, it’ll count as a conversion.
You can make your destination goals require users to have visited other pages first by using a funnel. If you edit the goal and switch “Funnel” on, you can specify the steps leading up to the goal. This means you can make sure that you don’t record goal conversions when users land directly on your thank-you pages.
You can also use it to separate out different kinds of goal conversions. For example, if you use the same thank-you page for multiple forms, you could have one goal where the funnel involves traveling through one form page, and another goal which involves traveling through another.
This will work if you:
Have a smaller (and fairly static) number of different goals.
There is a small (and fairly static) number of ways users can legitimately complete each goal.
However, funnel steps don’t allow things like regex, so they aren’t very flexible. Also, you can only use funnels with destination-type goals. So, funnels won’t help if:
Your goals are event-based.
You have lots of ways users could reach a goal.
You have multiple teams managing the site, and it doesn’t make sense to keep track of all the ways users could reach a goal.
You should be aware that if you have a problem like internal UTMs or sessions timing out, these form funnels can mean you stop recording some conversions you should be. Seriously, make sure those problems are fixed.
The ideal approach: event-based goals
The ideal approach involves using event-based conversions rather than destination-based ones. You work with your developers so that as the users complete the form you tell GA that an event has occurred, rather than GA having to wait for a thank-you page pageview. GA then records each instance of that event as a Goal conversion.
Below is the criteria for one event-based goal conversion, if you haven’t seen them before and are struggling to picture how they’re set up. It records a conversion for this goal any time GA receives an event of the category “thank_you_page”:
The reason this is ideal is, you’ll only record a conversion when the user actually does what you want them to do. Most conversion goals based on pageviews are just us trying to guess what the user has done. That’s why you run into problems with destination-based goals, like users landing directly on your thank-you page without completing the form you wanted them to complete.
You might think it’s a bit strange to leave this “ideal” solution until so late in the post, but I’m doing so because this is often not the simplest solution. It can require the most work on the developer side, and you could be using something built into your CMS that your dev team has to edit, or even worse, you could be working with an external form solution that they have to hack their way into.
I’m bringing this solution up at this point because if you don’t already have this in place, you’ll need to convince someone to do it. Their first question may be “have you considered other options?” When you have that conversation, you can say:
We’ve made sure we’re only recording conversions on the right pages.
We’ve made sure users aren’t getting to those pages in ways we can prevent.
We’ve made sure there aren’t other issues with how we’re tracking the site.
Our conversion data is being polluted in a way we can’t prevent because we have to rely on thank-you pageviews.
We can’t filter out those conversions using Google Analytics.
The best way to make sure our data is accurate is to use events, and the most accurate events to use are ones that only occur when the user does exactly what we want them to.
If you can help me I’ll be your best friend.
An alternative to Google Analytics funnels
It could turn out that the events-based solution above is impossible. Life has its frustrations, we soldier on.
An alternative is to switch to event-based conversions anyway and use Tag Manager to handle it all yourself. Using Tag Manager and cookies, you can create a more flexible version of GA’s funnel to only send conversion events when users land on a thank-you page having visited a qualifying page. How does that work? In short:
When a user visits one of your qualifying pages, you put a cookie in their browser.
When the user loads a thank-you page, you check for the cookie, and, if it exists, you send a conversion event to Google Analytics. If it doesn’t, you don’t.
Then you clear the cookie.
That means you won’t record the following false conversions:
Users landing direct on thank-you pages.
Users accidentally clicking to thank-you pages when they haven’t visited the relevant form.
Users leaving the thank-you tab open, or bookmarking it, and clicking back to it later after their GA session expires.
The section below gets into some specific Tag Manager terminology (the most confusing being that a “Custom Event” and a “Google Analytics Event” are two different things entirely).
Some terminology to know
I’ve color coded Tag Manager terminology in blue and all Google Analytics terminology in orange, but if you find yourself getting lost, you might want to read around a bit or talk to a knowledgeable colleague or consultant.
Event: Something we send to Google Analytics to record a specific action.
Custom event: Something that happens on the web page, which we can use as part of the criteria for a Tag Manager trigger.
Trigger: A set of conditions we lay out in Tag Manager. When these conditions are all fulfilled at the same time, the trigger fires and usually activates a tag.
Tag: Something in Tag Manager that does something. This sounds vague because it could be almost anything from sending an event to Google Analytics to completely rewriting the page.
Variable: A piece of information in Tag Manager that we can easily reference in triggers, tags, or other variables.
Data layer: Structured information on the page which makes it easier to pass information to Tag manager.
How to filter conversions with Tag Manager
1. Make sure Google Tag Manager is installed on your site
It’ll need to be on every page. Google has shared a Tag Manager quick-start guide if you need further guidance.
If you’re switching from standard GA code to Tag Manager, make sure you don’t include both GA and Tag Manager, or you’ll double-count.
2. Tell Tag Manager every time a thank-you page is loaded
We’ll assume your thank-you pages are all the same type of page, so you can reasonably say to your dev team, “please make this change to all of our thank you pages”. Ask them to add something like the script below.
Example script <script> window.dataLayer.push({    "event": "conversion" }); </script>  
If you need to test this process before getting the devs involved, you can try adding the code yourself by pasting it into the console using Chrome DevTools.
When the page loads, that script will add information to the data layer. Tag Manager will detect the change, and you can use it as one of the conditions for a trigger. In this case, Tag Manager would detect a Custom Event called conversion as this data is added. We’ll come back to that.
3. Tell Tag Manager every time a qualifying page is loaded
We’ll also assume there are some similarities between your qualifying pages. For one thing, they’ll probably all have a form on them. You can coordinate with your dev team to automatically add/activate a script any time one of those forms is added.
Example script <script> window.dataLayer.push({  "event": "qualifying" }); </script>
In this case, you’d see a Custom Event called qualifying. Again, you can test this by pasting directly into Console.
4. Whenever a user lands on a qualifying page, set a cookie
You’ll use your “qualifying” Custom Event as the criteria for a trigger. Below is a screenshot of the trigger setup:
Then you’ll create a tag which will be activated by that trigger. The tag will add some content to the page, in this case adding JavaScript (even though the tag type specifies HTML). The JavaScript will run as soon as it’s added and set a cookie for the user, that way you can pass information from one page to another.
Example script <script> // Get time 30 minutes from now (this is because the default GA session timeout // is half an hour and we want our cookie timeout to match) var dt = new Date(); dt.setHours( dt.getHours() + 0.5 );
// Set a cookie called ‘qualified’ with the value being ‘true’ which expires in 30 minutes document.cookie = "qualified=true; path=/; expires="+dt; </script>
5. Get the cookie value
Use a Tag Manager variable to make sure you’re detecting the value of the cookie, which will give you the current value of your “qualified” cookie each time you check.
6. Determine whether you should filter the conversion
In step two, you created a dataLayer event that will occur on all of your final conversion pages.
Now you create a trigger which fires on your “conversion” event.
Then create a tag which is activated by that trigger, and creates another Custom Event.
Below is the custom HTML to add. It checks if your qualifying cookie is set to “true”, which shows the user has already visited a qualifying page this session. If it is true, you create another Custom Event called “create_filtered_conversion”. If it’s false, you don’t. Either way, delete the cookie by setting its expiry time to be far in the past.
Example script <script> // When we are about to fire a conversion - check if we should. // If we should - create an event that will trigger the conversion // otherwise, don’t. Either way - clear the cookie
// Get variables var isQualified =
// Check if the conversion is qualified if (isQualified === "true"){   // If the user has a qualifying cookie   window.dataLayer.push({   "event": "conversion_confirmed",   }); } else {   // Do nothing if we have determined the conversion shouldn't fire   "" }
// Set cookie expiry in the past to clear it document.cookie = "qualified=false; path=/; expires=Thu, 01 Jan 1970 00:00:00"; </script>
7. Send event to GA
First you create a trigger which is waiting for that “conversion_confirmed” event.
Then you create a tag, activated by the trigger above, which sends the relevant event to GA. The specifics of the event sent to GA can be whatever you want, you just need to make sure they match the criteria of your goal in GA.

8. Don’t switch off your old conversions straight away
One nice thing about this is you can run it alongside your existing conversion tracking to see how often conversions are being filtered out. Keep your old conversion setup running for a while (how long depends on how often you get conversions).
Watch the two numbers and check if you’re filtering out loads of conversions. This check will help you spot mistakes in either the old setup or the new one.
Let me know what you think
Google Analytics will never be a perfect record of everything on your website, but these checks and processes should help you weed out some of the ways it can mislead you.
What do you think? What GA improvements do you think people have been missing? Let me know in the comments or on Twitter @robinlord8.
Sign up for The Moz Top 10, a semimonthly mailer updating you on the top ten hottest pieces of SEO news, tips, and rad links uncovered by the Moz team. Think of it as your exclusive digest of stuff you don't have time to hunt down but want to read!
0 notes
nutrifami · 3 years
Text
Avoiding False Conversions in Google Analytics
Posted by R0bin_L0rd
Preface
The first half of this post is a quick rundown of some of the standard ways in which your conversions could be going awry.
The second half of this post — everything after “How to filter conversions with Tag Manager” is an advanced way of intelligently filtering conversions using Tag Manager and cookies.
If you’re confident you’ve already covered your bases, feel free just to skip to the advanced section, I just feel it’s important to go through some of the basic stuff before diving into more complex solutions.
Avoiding false conversions
Aside from failing to record important data, one of the best ways to screw up your analytics is to record the wrong thing and lump it in with all the times you’ve recorded the right thing.
For example: if you’re counting conversions when you shouldn’t be, that can screw up automated ad bidding, how much you value individual channels, or even how well you think your business is doing. For this post, we’ll be referring to this issue as “false conversions”.
There are a huge number of ways you can track conversions in Google Analytics, and a huge number of ways to screw it up. This post is going to focus on some of the main ways you can mess up conversions when you’re basing them on users completing a form and then landing on a thank-you page.
We’ll cover:
Some useful tools
Things to check — how might users be accidentally converting?
How to protect destination-based goals from false conversions
An ideal event-based goal approach
How to protect event-based goals from false conversions
Useful tools
The tools below will help you with some of the checks in this post.
Chrome DevTools
F12 will open Chrome DevTools (you may need to press the “function” key depending on your keyboard). You can test JavaScript in “Console”, and view active cookies in “Application”.
Google Tag Manager preview
Google Tag Manager has a new preview which will show you what happens on a series of pages over time.
Adswerve dataLayer Inspector
This plugin summarizes dataLayer information in Chrome Console.
Analytics Tracking Monitor plugin
I’ve found this plugin really useful for checking what information is being sent to GA. One nice feature is being able to block hits from actually being sent to GA while recording what would be sent.
Tag Assistant
The Chrome Tag Assistant plugin will show you what Tag Manager tags are present on the page. If you click to record the session, it’ll also give you a breakdown of everything that’s happened on each page. That said — I don’t tend to rely on the recordings as much if I have Tag Manager access, because a lot of the useful information is covered between the new GTM preview and the tracking monitor plugin.
Tag Mapper
I created a free Tag Mapper tool to make it easier to see what impact Tag Manager changes might have. If you’re planning on changing something in your GTM account, you can see what else might be impacted. Likewise, if you’ve noticed that something is broken, it can help you find the root cause.
Things to check
It can be tempting to leap straight to a catch-all solution, but if you’re recording conversions when you shouldn’t be, that could be because your website visitors are doing things they shouldn’t be.
Let’s start with a quick rundown of checks you should do to make sure you’re not making the numbers look right by just ignoring problems on your site.
1. Are you only recording conversions on thank-you pages?
To check if you’re recording conversions on pages you shouldn’t be (like, every page on your site or something) have a quick look at the Reverse Goal Path report in Google Analytics:
Conversions > Goals > Reverse Goal Path.
The first column on the left should show you where your goal conversions are taking place, unless you’re doing something unusual. If you’re seeing a bunch of pages in that column which you don’t expect, that’s a sign you need to change your criteria for conversions.
One thing to bear in mind here: if you’re recording conversions based on events rather than pageviews, and you’re seeing the wrong page appearing in that left-hand column, make sure your conversion event only ever fires after your pageview.
2. Are you linking to conversion pages in other ways besides form completions?
If you’re using any goals based on a user loading a specific page (like a thank-you page), and you know you’re only recording conversions on thank-you pages, another way you could be screwing things up is accidentally linking to those thank-you pages. If a user can click on the wrong link and end up on a conversion page, you need to fix that.
One way to check for this is using a tool like Screaming Frog to crawl the site and just see if your conversion pages appear. If they appear at all, you know that’s probably a problem. To find out how to fix the problem, you can select the offending pages and check the “Inlinks” panel, which will give you a list of where you’re linking to them.
3. Are users landing directly on thank-you pages?
A quick way to check if users are landing on your thank-you pages is to use segments. If you create a segment where the landing page is your thank-you page, you can get an idea of how often Google Analytics thinks users are landing on your conversion page.
Below, you can see a screenshot of the segment interface. I’ve set it to include any session where the first interaction was a user landing on a thank-you landing page. As you can see, that was the case for 339 sessions on this site:
Once you see how often users are landing on your thank-you pages, you can pinpoint the sources which are bringing those users to the site.
Below, I’ve applied a “lands on thank-you page” segment to the Source/Medium report, and it looks like we’re getting a bunch of direct sessions, but also some CPC sessions, and organic sessions elsewhere, too:
An important thing to bear in mind here is that this is based on what Google Analytics thinks is happening. It doesn’t necessarily mean users are landing on these pages directly from adverts. In fact, in this example, we know this isn’t always the case, and sometimes it’s a symptom of our tracking code being broken or confused in another way. Even so, it gives us some things to investigate.
For example:
Do we have adverts or other activity pointing straight to conversion pages?
Are our conversion pages indexed in Google?
Do we have a page in the middle of our conversion flow that isn’t being tracked?
Is our tracking code broken, or are users doing things on-site which would confuse GA?
3.1 Do you have adverts or other activity pointing straight to conversion pages?
I won’t be able to walk you through all of this, but all advertising platforms should allow you to check active landing pages. It’s also important to make sure that you don’t have any affiliates linking directly to conversion pages — either accidentally or maliciously — as you could be paying them a lot more than they deserve.
It may be harder to check non-paid links, like social media activity. That said, it’s worth spending the time checking. If you find you’re linking to these conversion pages by accident, you can work with relevant teams to put policies in place for that in future.
3.2 Are your conversion pages indexed in Google?
Google can be a frequent cause of conversion page issues. It’s a ravenous crawler. It’ll follow links inside and outside of your site, and if there’s a machine-crawlable link to your thank-you page, it’ll probably find it.
A quick way to check if Google has saved your thank-you pages (and might be sending users straight to them) is to search for the pages in Google.
Using “site:” filters Google results to just pages on your site. Using “inurl:” filters results to just pages that contain a specific string.
Below is an example of a check we did for one of our clients. We found that they had a lot of “thank-you” pages in the index (over 600). Some of those pages were fine, but it highlighted a number of conversion pages for us to deal with:
3.3 Is your tracking code broken, or are users doing things on-site which would confuse GA?
We don’t have time to go through all the things that could go wrong here. Some things to check are:
Are you missing tracking code on some pages? Perhaps you’re failing to record the user before they land on the thank-you page.
Do you have different versions of Google Analytics on different pages? This can, again, cause confused or split sessions.
Are you including UTM parameters on any internal links? Any website crawler should help you find this.
Do you have the wrong timezone set in GA? Sessions can’t cross “midnight” — if they do, GA will split them into two separate sessions.
Are you including important information on the thank-you page that could cause users to bookmark the page, or try to come back to it later? One solution here is to include pretty much nothing visitor-specific on the thank-you page, and assure them that you’ll email them details. It’s worth testing this to make sure it doesn’t hurt visitor confidence.
Do you have any forms, that take more than half an hour to fill out, and don’t record interactions in the meantime? You can avoid this by splitting the form into different pages and tracking when visitors fill out a form field or when they hit errors. Entirely aside from what we’re looking at in this post, but all of these things should help you make your forms more user-friendly.
Once you have all of those checked off, you can start to look at ways to improve the way you filter your conversion data.
How to protect destination-based goals from false conversions
If you have your goal type set to “Destination” in Google Analytics, that means that any time GA records a pageview for a specific page, it’ll count as a conversion.
You can make your destination goals require users to have visited other pages first by using a funnel. If you edit the goal and switch “Funnel” on, you can specify the steps leading up to the goal. This means you can make sure that you don’t record goal conversions when users land directly on your thank-you pages.
You can also use it to separate out different kinds of goal conversions. For example, if you use the same thank-you page for multiple forms, you could have one goal where the funnel involves traveling through one form page, and another goal which involves traveling through another.
This will work if you:
Have a smaller (and fairly static) number of different goals.
There is a small (and fairly static) number of ways users can legitimately complete each goal.
However, funnel steps don’t allow things like regex, so they aren’t very flexible. Also, you can only use funnels with destination-type goals. So, funnels won’t help if:
Your goals are event-based.
You have lots of ways users could reach a goal.
You have multiple teams managing the site, and it doesn’t make sense to keep track of all the ways users could reach a goal.
You should be aware that if you have a problem like internal UTMs or sessions timing out, these form funnels can mean you stop recording some conversions you should be. Seriously, make sure those problems are fixed.
The ideal approach: event-based goals
The ideal approach involves using event-based conversions rather than destination-based ones. You work with your developers so that as the users complete the form you tell GA that an event has occurred, rather than GA having to wait for a thank-you page pageview. GA then records each instance of that event as a Goal conversion.
Below is the criteria for one event-based goal conversion, if you haven’t seen them before and are struggling to picture how they’re set up. It records a conversion for this goal any time GA receives an event of the category “thank_you_page”:
The reason this is ideal is, you’ll only record a conversion when the user actually does what you want them to do. Most conversion goals based on pageviews are just us trying to guess what the user has done. That’s why you run into problems with destination-based goals, like users landing directly on your thank-you page without completing the form you wanted them to complete.
You might think it’s a bit strange to leave this “ideal” solution until so late in the post, but I’m doing so because this is often not the simplest solution. It can require the most work on the developer side, and you could be using something built into your CMS that your dev team has to edit, or even worse, you could be working with an external form solution that they have to hack their way into.
I’m bringing this solution up at this point because if you don’t already have this in place, you’ll need to convince someone to do it. Their first question may be “have you considered other options?” When you have that conversation, you can say:
We’ve made sure we’re only recording conversions on the right pages.
We’ve made sure users aren’t getting to those pages in ways we can prevent.
We’ve made sure there aren’t other issues with how we’re tracking the site.
Our conversion data is being polluted in a way we can’t prevent because we have to rely on thank-you pageviews.
We can’t filter out those conversions using Google Analytics.
The best way to make sure our data is accurate is to use events, and the most accurate events to use are ones that only occur when the user does exactly what we want them to.
If you can help me I’ll be your best friend.
An alternative to Google Analytics funnels
It could turn out that the events-based solution above is impossible. Life has its frustrations, we soldier on.
An alternative is to switch to event-based conversions anyway and use Tag Manager to handle it all yourself. Using Tag Manager and cookies, you can create a more flexible version of GA’s funnel to only send conversion events when users land on a thank-you page having visited a qualifying page. How does that work? In short:
When a user visits one of your qualifying pages, you put a cookie in their browser.
When the user loads a thank-you page, you check for the cookie, and, if it exists, you send a conversion event to Google Analytics. If it doesn’t, you don’t.
Then you clear the cookie.
That means you won’t record the following false conversions:
Users landing direct on thank-you pages.
Users accidentally clicking to thank-you pages when they haven’t visited the relevant form.
Users leaving the thank-you tab open, or bookmarking it, and clicking back to it later after their GA session expires.
The section below gets into some specific Tag Manager terminology (the most confusing being that a “Custom Event” and a “Google Analytics Event” are two different things entirely).
Some terminology to know
I’ve color coded Tag Manager terminology in blue and all Google Analytics terminology in orange, but if you find yourself getting lost, you might want to read around a bit or talk to a knowledgeable colleague or consultant.
Event: Something we send to Google Analytics to record a specific action.
Custom event: Something that happens on the web page, which we can use as part of the criteria for a Tag Manager trigger.
Trigger: A set of conditions we lay out in Tag Manager. When these conditions are all fulfilled at the same time, the trigger fires and usually activates a tag.
Tag: Something in Tag Manager that does something. This sounds vague because it could be almost anything from sending an event to Google Analytics to completely rewriting the page.
Variable: A piece of information in Tag Manager that we can easily reference in triggers, tags, or other variables.
Data layer: Structured information on the page which makes it easier to pass information to Tag manager.
How to filter conversions with Tag Manager
1. Make sure Google Tag Manager is installed on your site
It’ll need to be on every page. Google has shared a Tag Manager quick-start guide if you need further guidance.
If you’re switching from standard GA code to Tag Manager, make sure you don’t include both GA and Tag Manager, or you’ll double-count.
2. Tell Tag Manager every time a thank-you page is loaded
We’ll assume your thank-you pages are all the same type of page, so you can reasonably say to your dev team, “please make this change to all of our thank you pages”. Ask them to add something like the script below.
Example script <script> window.dataLayer.push({    "event": "conversion" }); </script>  
If you need to test this process before getting the devs involved, you can try adding the code yourself by pasting it into the console using Chrome DevTools.
When the page loads, that script will add information to the data layer. Tag Manager will detect the change, and you can use it as one of the conditions for a trigger. In this case, Tag Manager would detect a Custom Event called conversion as this data is added. We’ll come back to that.
3. Tell Tag Manager every time a qualifying page is loaded
We’ll also assume there are some similarities between your qualifying pages. For one thing, they’ll probably all have a form on them. You can coordinate with your dev team to automatically add/activate a script any time one of those forms is added.
Example script <script> window.dataLayer.push({  "event": "qualifying" }); </script>
In this case, you’d see a Custom Event called qualifying. Again, you can test this by pasting directly into Console.
4. Whenever a user lands on a qualifying page, set a cookie
You’ll use your “qualifying” Custom Event as the criteria for a trigger. Below is a screenshot of the trigger setup:
Then you’ll create a tag which will be activated by that trigger. The tag will add some content to the page, in this case adding JavaScript (even though the tag type specifies HTML). The JavaScript will run as soon as it’s added and set a cookie for the user, that way you can pass information from one page to another.
Example script <script> // Get time 30 minutes from now (this is because the default GA session timeout // is half an hour and we want our cookie timeout to match) var dt = new Date(); dt.setHours( dt.getHours() + 0.5 );
// Set a cookie called ‘qualified’ with the value being ‘true’ which expires in 30 minutes document.cookie = "qualified=true; path=/; expires="+dt; </script>
5. Get the cookie value
Use a Tag Manager variable to make sure you’re detecting the value of the cookie, which will give you the current value of your “qualified” cookie each time you check.
6. Determine whether you should filter the conversion
In step two, you created a dataLayer event that will occur on all of your final conversion pages.
Now you create a trigger which fires on your “conversion” event.
Then create a tag which is activated by that trigger, and creates another Custom Event.
Below is the custom HTML to add. It checks if your qualifying cookie is set to “true”, which shows the user has already visited a qualifying page this session. If it is true, you create another Custom Event called “create_filtered_conversion”. If it’s false, you don’t. Either way, delete the cookie by setting its expiry time to be far in the past.
Example script <script> // When we are about to fire a conversion - check if we should. // If we should - create an event that will trigger the conversion // otherwise, don’t. Either way - clear the cookie
// Get variables var isQualified =
// Check if the conversion is qualified if (isQualified === "true"){   // If the user has a qualifying cookie   window.dataLayer.push({   "event": "conversion_confirmed",   }); } else {   // Do nothing if we have determined the conversion shouldn't fire   "" }
// Set cookie expiry in the past to clear it document.cookie = "qualified=false; path=/; expires=Thu, 01 Jan 1970 00:00:00"; </script>
7. Send event to GA
First you create a trigger which is waiting for that “conversion_confirmed” event.
Then you create a tag, activated by the trigger above, which sends the relevant event to GA. The specifics of the event sent to GA can be whatever you want, you just need to make sure they match the criteria of your goal in GA.

8. Don’t switch off your old conversions straight away
One nice thing about this is you can run it alongside your existing conversion tracking to see how often conversions are being filtered out. Keep your old conversion setup running for a while (how long depends on how often you get conversions).
Watch the two numbers and check if you’re filtering out loads of conversions. This check will help you spot mistakes in either the old setup or the new one.
Let me know what you think
Google Analytics will never be a perfect record of everything on your website, but these checks and processes should help you weed out some of the ways it can mislead you.
What do you think? What GA improvements do you think people have been missing? Let me know in the comments or on Twitter @robinlord8.
Sign up for The Moz Top 10, a semimonthly mailer updating you on the top ten hottest pieces of SEO news, tips, and rad links uncovered by the Moz team. Think of it as your exclusive digest of stuff you don't have time to hunt down but want to read!
0 notes