We recently upgraded from Launch to DTM and I'm working on cleaning up our architecture and implementation. I've got 2 questions...
1. For some reason, they put the dataLayer just above the footer. That's poor design right? I've never seen it so far down the page. Does it need to be in-between the header and footer code but in the header for best practices?
2. In Launch, I can't find a header and footer code, only one embed code. Are both the header and footer no longer necessary and only one string is needed now?
trying to give you some feedback on your questions:
1) technically it doesn't matter a lot where you have your dataLayer. I heard devs voting for both options, header and at the end of body - don't know if either of them is poor design by default.
BUT: the sooner the browser reaches the dataLayer, the earlier you can access those information within Launch (because the code is processed and available). so from an analytics point of view you might want it as high as possible!
on the other hand, it might slow down the page/real content a little bit because the browser needs to process this code which is not necessary for the page itself.
overall: the lower the dataLayer, the longer you need to wait with pageview tracking - and might miss some user that navigate really fast or close the window before tracking ...
2) you can go with or without the additional code "_sattelite.bageBottom();" at the end of the page. this is only an additional trigger to start the pageview tracking. if you don't have this code, you can't take "bageBottom" as trigger, but you can take "library loaded" or "dom ready" as well.
I personally still have the "pageBottom" code on the page especially on pages where I have a hidden div at the end of the DOM. that means, using this trigger right after the dataLayer makes me comfortable about having the right timing to track (because the browser processes the dataLayer THEN triggers analytics.
but if you have sort of "dataLayer.push()" and use eg. the "data layer manager extension", there is no need for this additional trigger since you only rely on the dataLayer ...
remark: you can include the library both sync and async, look in the help docs about the difference (can't find the page right now...)