战争爆发前,鉴于中越两国的特殊关系及法国侵略越南给中国造成的严重威胁,再加上左宗棠、张之洞等主战派的强烈呼吁,清政府表面上一改往日的消极态度,一方面敦促李鸿章抓紧和法国谈判,另一方面增强了原驻北圻的桂军(广西清军)兵力,又命云南方面派兵出境,互为声援,并派人联络黑旗军援越抗法。但是,清政府知道自己的实力不济,再三训令清军不得主动出击,不得寻衅。这种自相矛盾的举措,大大便利了法国的侵略部署。
1883年12月初,北圻法军已增加到近万人,大部分集中在河内地区,作战准备基本就绪。而此时清军方面,负责北圻东线防务的广西巡抚徐延旭托病滞留谅山,所属四十四营一万五千六百人,分驻北宁、太原、高平、谅山等地。其中左路统领广西提督黄桂兰、右路统领广西道员赵沃共率二十五营九千六百人守北宁。后又新招募扩编十九营六千人。
负责西线防务的云贵总督岑毓英虽然奉命力保红河中游战略要地山西,但尚未启程,进驻山西的滇军仅有三个营,加上刘永福率领的黑旗军(十二营三千五人)和吏部主事唐景崧率领的少量桂军(二营八百人),山西守军共约五千人。
(一)山西失守
山西位于河内以西九十多里,是控制红河中上游的战略要地,也是清军联系东西线的主要通道。
刘永福在1883年9月11日率领黑旗军退守山西后,一直在不断地加强城防和沿岸河堤工事。刘永福命令部众加固城墙,从河岸到城北门筑起五重木栅,在河岸修筑炮台,每隔十丈放置一门铁炮,并在水面设木排、竹筏阻塞河道。城北为主要防御方向,集中黑旗军六营、桂军一营占据既设阵地,以控制河道,阻止敌人向北门进攻;城东也是重点防御方向,由黑旗军五营组成两道阵地,防敌陆路向东门攻击;唐景崧商调滇军督带张永清率三营由兴化到山西,防守西门;黑旗军一营、桂军一营配置于南门,以备机动;黄佐炎越军部署在南门外乡村中,相机策应。刘永福驻外城,唐景崧驻内城,督战指挥。
12月11日,法军新任远征军总司令孤拔率领六千多人,分水陆两路从河内出发向山西进军。一路由军舰十二艘,板船四十艘,载陆军三千二百余人,溯红河西上;另一路陆军两千六百余人沿红河南岸直扑山西。
14日上午9时,法军向山西城发起进攻,摧毁沿岸炮台,并在城东北方向登岸,登岸步兵迅速展开,向黑旗军阵地接近。黑旗军依托河堤阵地进行还击,使法军遭受严重损失而不能及时发起冲击。下午,刘永福调来东门的黑旗军主力,隐蔽地迂回到法军的左侧,并插入法军舰队与步兵之间,猛烈攻击法军侧翼,使其两面受击,而法军舰炮则不敢开炮射击。孤拔见形势危急,立即令法军转入防御,集中所有炮兵向迂回的黑旗军轰击。黑旗军迂回部队由于伤亡较大被迫撤退。下午4时,孤拔下达攻击令,法军向坚守河堤的黑旗军发起猛烈攻击。黑旗军顽强扼守阵地,以排枪射击大量杀伤敌人,迫使余敌溃退。法军大炮猛轰,步兵多次进行冲击。当法军迫近河堤时,黑旗军与敌人展开激烈的肉搏战。经过一个多小时的激战,法军以死伤士兵二百人、军官二十二人的代价夺取了河堤阵地。15日1时,唐景崧组织桂军和滇军乘夜进行反击,企图夺回阵地,但激战四小时仍未能获得成功。于是将城北守军撤至外城,依托土围分段坚守。15日上午双方调整部署。午后,法军开始向城西运动,企图夺取城西滇军据点,然后从城北、城西同时攻城。刘永福判明情况后,率黑旗军主力增援西门,并加强防御工事。这一天,法军大炮不停地轰击山西城。16日拂晓,法军多次猛攻北门,均未得逞。但守军伤亡较大,弹药告竭。法军同时进攻西门,炮火猛烈。西门城墙最终被法军炸毁。越奸阮廷润等人叛国投敌,其余越军也贪生怕死,穿上白衣,打开城门向法军投降。危急之下,刘永福、唐景崧督军坚守到深夜,不得已各自率军退出山西,转至兴化。26日,山西沦陷。
山西的首战失利,使清军失去了威胁河内的前哨阵地,丢掉了控制红河的战略要点,北宁亦失犄角之势。滇军随即撤出兴化、宣光,使滇桂联系全断,东西两线协同作战增加了更大困难。这样,清军在越南北圻作战便受到了严重影响。
(二)北宁失守
北宁是清军在越南北圻所据守的战略要地。
北宁守军经过一年多的准备,工事不断加强,兵力逐步增加,到战役开始前,总兵力已达五十八营两万四千余人。其兵力部署是:副将党敏宣率八营防守北宁东六十余里之三江口,以阻法军溯六头江包抄北宁后路;总兵陈德贵率四营,扼守北宁东北之扶朗,以阻止敌舰船沿江进攻涌球威胁北宁;副将韦和礼率十营分守北宁东南之桂阳、左河,刘永福黑旗军十二营守揽山,阻敌陆路主力进攻北宁;总兵陈德朝率兵八营驻守北宁南五十余里之新河口和慈山,以阻敌沿慈山大路进攻北宁;参将李应章率一营防守北宁以西之金英,以扼山西入北宁之通道;总兵陈朝纲率两营防守北宁城北八里之涌球(涌球北面临河,有两座土山,是北宁的屏障和安危相关要点);副将周炳林率四营防守涌球东五里之塞河处,以阻法军沿河而上,攻击涌球;黄桂兰、赵沃率亲兵两营、参将蒋大章率一营另两哨防守北宁城池。此外,为保持与谅山的联系,在北宁与谅山之间的谅江部署有五营。
山西失陷后,北宁受到法军来自海阳、河内、山西三个方向的严重威胁。因此清廷十分惊恐,多次下达谕旨,要防军固守北宁。但统帅徐延旭老迈昏庸,刚愎自用,对现代战争的战略战术一无所知。他在清流派人物的吹嘘荐举下,受到清政府破格提拔,骗得了巡抚高官之后,即致电清廷告病,以种种借口拒绝亲临北宁前线,后来在清廷的多次催促之下才勉强出关,驻守谅山。徐延旭把北宁的作战指挥权交给了左路统领广西提督黄桂兰,和右路统领广西道员赵沃。黄桂兰虽然是行伍出身,但他的部队装备落伍,火炮数量少,步兵中只有部分士兵使用进口或仿制的比较先进的步枪,且子弹稀缺;不少士兵仍使用刀矛、鸟枪、土枪等杂式武器。赵沃不仅昏庸无识,而且年老多病,在形势紧张时,多次上书称病告假,但却受到徐延旭的信任。黄、赵二人地位相当,互不相让,因此左、右两路军互不统属,各成系统,此乃兵家之大忌。况且,前线的将领们此时已经被上面的政策弄糊涂了,不知道到底是和还是战,他们以为驻军只是摆摆样子而已,生怕自己的挑衅坏了和议大局,因此备战并不认真。
1884年2月,米乐接替孤拔成为法国远征军少将总司令,率领一万六千人进军北宁,意图把中国军队彻底赶出越南。
3月7日,米乐、波里也率第一旅六千余人渡过红河,8日以一部兵力由嘉林佯渡新河,制造出法军沿慈山大路向北宁进攻的假象,主力则沿新河南岸向东疾驰;同日,尼格里率第二旅六千余人、舰船二十余艘,从海阳出发沿太平江北上,上午9时开始攻击扶朗,清军陈德贵等营被法军包围。黄昏时分,陈德贵等营冲出敌围,败退六七里,扶朗失陷。
9—11日双方调整部署,清军将扶朗战场上败退下来的四营兵力重新做了部署,但没有增派兵力加强涌球水路的防御。此时,法军陆路进攻部队完成了准备。